Понимание возвращаемого значения `decode-time` (elisp) - PullRequest
0 голосов
/ 07 апреля 2019

После прочтения документации encode-time и decode-time я не понимаю, как они работают.

Моя проблема заключается в том, что encode-time возвращает два значениятогда как я ожидаю только одну (количество секунд с начала эпохи UNIX).Что именно означают эти два значения?

ELISP> (encode-time 0 0 0 1 1 1970 t)
(0 0)
ELISP> (encode-time 0 0 0 1 1 1971 t)
(481 13184)

Я запутался еще больше, потому что эти три вызова работают, но я не понимаю, как интерпретировать аргумент в первых двух случаях:

;; Ok this is what I expect from the documentation
ELISP> (decode-time
        (encode-time 0 0 0 1 1 1971 t))
(0 0 0 1 1 1971 5 nil 0)

;; This is also what I expected, given it's the same than above, but I don't understand the meaning of the arguments
ELISP> (decode-time '(481 13184))
(0 0 0 1 1 1971 5 nil 0)

;; I kind of understand the following: here 481  is considered the seconds since UNIX epoch,
;; and 13184 is the difference in seconds from UTC.
;; The returned value, is the date (UNIX epoch + 481 seconds)
;; expressed in a timezone 13184 seconds ahead of UTC (45 47 3 1 1 1970 = 13665 seconds
;; and 13665−13184 = 481) 
ELISP> (decode-time 481 13184)
(45 47 3 1 1 1970 4 nil 13184)

Обратите внимание, что для всех приведенных выше примеров я установил (set-time-zone-rule t), чтобы избежать необходимости работать с часовыми поясами.

Ответы [ 2 ]

2 голосов
/ 07 апреля 2019

(481 131184) представляет количество секунд как (HIGH LOW), где HIGH - старшие биты, а LOW - младшие 16 бит.Т.е. реальное количество секунд составляет

(+ (* 481 65536) 13184) == 31536000
1 голос
/ 08 апреля 2019

Глядя на документацию:

(decode-time &optional TIME ZONE)

Декодируйте значение времени как (SEC MINUTE HOUR DAY MONTH YEAR DOW DST UTCOFF). Необязательное TIME должно быть списком (HIGH LOW. IGNORED), начиная с 'current-time' и 'file-attribute' или nil, чтобы использовать текущее время.Это также может быть одно целое число секунд с начала эпохи.Устаревшая форма (HIGH. LOW) также все еще принимается.

Таким образом, мы можем видеть, что ожидаемый формат представляет собой список со значениями "HIGH" и "LOW" (и, возможно, некоторой дополнительной информацией),Следуя этому направлению к current-time, мы даем дополнительное объяснение:

(current-time)

Возвращает текущее время в виде количества секунд с 1970-01-01 00:00:00.Время возвращается в виде списка целых чисел (HEC LOW USEC PSEC).HIGH имеет младшие значащие биты, а LOW - младшие 16 бит.USEC и PSEC - это микросекунды и пикосекунды.

Почему Emacs использует этот, казалось бы, сложный формат?Несомненно, ответ прост: Emacs устарел, и ему нужно было работать с системами, в которых были доступны только 16-битные целые числа.

Глядя в руководство, Mx elisp-index-search для current-time приводит нас к (elisp)Time of Day:

Большинство этих функций представляют время в виде списка из четырех целых чисел (SEC-HIGH SEC-LOW MICROSEC PICOSEC) '.Это количество секунд от «эпохи» (1 января 1970 года в 00:00 UTC) по формуле: HIGH * 2 ** 16 + LOW + MICRO * 10 ** - 6 + PICO * 10 ** -12.Возвращаемое значение 'current-time' представляет время, используя эту форму, также как и отметки времени в возвращаемых значениях других функций, таких как 'file-attribute' (* note Примечание Определение file-attribute: :).В некоторых случаях функции могут возвращать двух- или трехэлементные списки, при этом пропущенные компоненты MICROSEC и PICOSEC по умолчанию имеют значение 0примите более общий формат «значение времени», который может быть списком целых чисел, как указано выше, или одним числом в секундах с начала эпохи, или «ноль» для текущего времени.Вы можете преобразовать значение времени в удобочитаемую строку, используя 'current-time-string' и 'format-time-string', в список целых чисел, используя 'seconds-to-time', и в другие формы, используя 'decode-time 'и' float-time '. Эти функции описаны в следующих разделах.

Следовательно, вы можете, например, передать единственное 32-битное целое число метки времени Unix в decode-time

(decode-time 1554670400)
=> (20 53 8 8 4 2019 1 nil 43200)

Вы также можете использовать format-time-string, чтобы получить одно целое значение:

(string-to-number (format-time-string "%s" (current-time)))
...