Spec-Zone.ru › Elisp

Преобразование времени

Эти функции преобразуют значения времени (см. Время суток) в метки времени Lisp или в календарные данные и обратно.

Многие операционные системы используют 64-разрядные целые числа со знаком для подсчёта секунд и могут представлять время в далёком прошлом или будущем. Однако возможности некоторых систем более ограничены. Например, старые операционные системы, использующие 32-разрядные целые числа со знаком, обычно поддерживают только время с 1901-12-13 20:45:52 по 2038-01-19 03:14:07 по всемирному времени.

Функции календарного преобразования используют григорианский календарь даже для дат, предшествующих его введению, а также для дат в далёком прошлом или будущем, для которых григорианский календарь крайне неточен и расходится с общепринятой практикой в таких научных областях, как астрономия и палеонтология, где используют продолжительность года по юлианскому календарю. Нумерация лет ведётся с 1 года до н. э.; в отличие от традиционной григорианской нумерации, нулевой год не пропускается. Например, номер года −37 соответствует 38 году до н. э.

Функция: time-convert time form

Эта функция преобразует значение времени в метку времени Lisp.

Аргумент form задаёт форму возвращаемой метки времени. Если form — символ integer, функция возвращает целое число секунд. Если form — положительное целое число, оно задаёт частоту часов, и функция возвращает метку времени в виде пары целых чисел (ticks . form). Если form — t, функция рассматривает его как положительное целое число, подходящее для представления метки времени; например, оно рассматривается как 1000000000, если time — nil, а разрешение метки времени платформы составляет одну наносекунду. Если form — list, функция возвращает список целых чисел (high low micro pico). Хотя сейчас значение form типа nil действует как list, в будущей версии Emacs это может измениться, поэтому вызывающим функциям, которым нужны метки времени в виде списка, следует явно передавать list.

Если time не является значением времени, функция сигнализирует об ошибке. В противном случае, если time нельзя представить точно, преобразование округляет его вниз, в сторону минус бесконечности. Если form — t, преобразование всегда выполняется точно, поэтому усечения не происходит, а разрешение возвращаемого значения не ниже разрешения time. В отличие от этого, хотя float-time также может преобразовать любое значение времени, не сигнализируя об ошибке, результат может быть неточным. См. Время суток.

Для повышения эффективности эта функция может возвращать значение, которое eq значению time или иным образом разделяет с ним структуру.

Хотя (time-convert nil nil) эквивалентно (current-time), последнее может работать немного быстрее.

(setq a (time-convert nil t))
⇒ (1564826753904873156 . 1000000000)
(time-convert a 100000)
⇒ (156482675390487 . 100000)
(time-convert a 'integer)
⇒ 1564826753
(time-convert a 'list)
⇒ (23877 23681 904873 156000)
Функция: decode-time &optional time zone form

Эта функция преобразует значение времени в календарные данные. Если не указать time, она декодирует текущее время; аналогично, по умолчанию zone используется текущее правило часового пояса. См. Правила часовых поясов. Операционная система ограничивает диапазон значений времени и часового пояса.

Аргумент form определяет форму возвращаемого элемента seconds, как описано ниже. Возвращаемое значение — список из девяти элементов:

(seconds minutes hour day month year dow dst utcoff)

Значения элементов:

seconds

Количество секунд, прошедших с начала минуты; форма описана ниже.

minutes

Количество минут, прошедших с начала часа; целое число от 0 до 59.

hour

Час суток; целое число от 0 до 23.

day

День месяца; целое число от 1 до 31.

month

Месяц года; целое число от 1 до 12.

year

Год; целое число, обычно большее 1900.

dow

День недели; целое число от 0 до 6, где 0 обозначает воскресенье.

dst

t, если действует летнее время, nil, если оно не действует, и −1, если эта информация недоступна.

utcoff

Целое число, обозначающее смещение от всемирного времени в секундах, то есть количество секунд к востоку от Гринвича.

Элемент seconds — неотрицательная метка времени Lisp, меньшая 61; обычно она меньше 60, за исключением положительных високосных секунд (если операционная система поддерживает високосные секунды). Если необязательный аргумент form равен t, для seconds используется та же точность, что и для time; если form равен integer, значение seconds усекается до целого числа. Например, если time — метка времени (1566009571321 . 1000), которая в типичных системах без високосных секунд обозначает 2019-08-17 02:39:31.321 UTC, то (decode-time time t t) возвращает ((31321 . 1000) 39 2 17 8 2019 6 nil 0), тогда как (decode-time time t 'integer) возвращает (31 39 2 17 8 2019 6 nil 0). Если form не указан или равен nil, сейчас по умолчанию используется integer, но в будущих выпусках Emacs это значение по умолчанию может измениться, поэтому вызывающим функциям, которым нужна определённая форма, следует указывать form.

Примечание о Common Lisp: В Common Lisp элементы dow, dst и utcoff имеют другие значения, а элемент second — целое число от 0 до 59 включительно.

Для доступа к элементам календарных данных (или их изменения) можно использовать функции доступа decoded-time-second, decoded-time-minute, decoded-time-hour, decoded-time-day, decoded-time-month, decoded-time-year, decoded-time-weekday, decoded-time-dst и decoded-time-zone.

Функция: encode-time time &rest obsolescent-arguments

Эта функция преобразует time в метку времени Lisp. Она может служить обратной функцией к decode-time.

Обычно первый аргумент — список (second minute hour day month year ignored dst zone), задающий декодированное время в формате decode-time. Значения элементов этого списка приведены в таблице в разделе decode-time. В частности, dst указывает, как интерпретировать метки времени во время перевода часов с летнего времени, когда метки времени повторяются. Если dst равен −1, значение летнего времени определяется автоматически; если он равен t или nil, возвращается метка времени с этим значением летнего времени, а если такой метки времени не существует, сигнализируется ошибка. К сожалению, значение dst, равное t или nil, не позволяет различить дублирующиеся метки времени, возникающие, когда часовой пояс на основе TZDB смещается дальше к западу от Гринвича. Например, оно не позволяет различить две метки времени стандартного времени 2020-12-27 01:30, если zone — ‘"Europe/Volgograd"’: в тот день в 02:00 стандартное время сместилось с 4 до 3 часов к востоку от Гринвича. Если нужно обрабатывать подобные ситуации, используйте вместо этого числовое значение zone для устранения неоднозначности.

Первый аргумент также может быть списком (second minute hour day month year), который обрабатывается так же, как список (second minute hour day month year nil -1 nil).

В устаревающем соглашении о вызове этой функции можно передать шесть или более аргументов. Первые шесть аргументов — second, minute, hour, day, month и year — задают большую часть компонентов декодированного времени. Если аргументов больше шести, последний аргумент используется как zone, а остальные дополнительные аргументы игнорируются, благодаря чему работает (apply #'encode-time (decode-time ...)). В этом устаревающем соглашении dst равен −1, а для zone по умолчанию используется текущее правило часового пояса (см. Правила часовых поясов). При обновлении устаревшего вызова убедитесь, что более современный эквивалент в виде списка содержит 9 элементов, а элемент dst равен −1, а не nil.

Номера лет меньше 100 не обрабатываются особым образом. Если они должны обозначать годы после 1900 или после 2000 года, измените их самостоятельно перед вызовом encode-time. Операционная система ограничивает диапазон значений времени и часового пояса. Однако метки времени от начала эпохи до ближайшего будущего поддерживаются всегда.

Функция encode-time является приблизительной обратной функцией к decode-time. Например, можно передать выходное значение последней функции первой следующим образом:

(encode-time (decode-time ...))

Простую арифметику дат можно выполнять, используя выходящие за допустимый диапазон значения для seconds, minutes, hour, day и month; например, день 0 означает день перед указанным месяцем. Будьте осторожны: в некоторых случаях такой подход может не сработать. Например:

;; Try to compute the time one month from now.
;; Watch out; this might not work as expected.
(let ((time (decode-time)))
  (setf (decoded-time-month time)
        (+ (decoded-time-month time) 1))
  time)

К сожалению, этот код может работать не так, как ожидалось, если полученное время недействительно из-за различий в продолжительности месяцев, переходов на летнее время, изменений часового пояса или отсутствующих високосных дней либо секунд. Например, если выполнить этот код 30 января, он даст несуществующую дату 30 февраля, которую encode-time скорректирует на начало марта. Аналогично, прибавление четырёх лет к 29 февраля 2096 года даст несуществующую дату 29 февраля 2100 года; прибавление одного часа к 01:30 13 марта 2022 года в Нью-Йорке даст метку времени 02:30, которой не существует, поскольку в этот день часы перевели вперёд с 02:00 на 03:00. Чтобы избежать некоторых (но не всех) проблем, можно основывать вычисления на середине затрагиваемой единицы, например, начинать с 15-го числа месяца при прибавлении месяцев. Также можно использовать библиотеки calendar и time-date.

Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Time-Conversion.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API