Где високосные секунды в JavaScript?
Когда я использую
- пользовательский файл zoneinfo для TAI или /usr/share/zoneinfo-leaps и
- модифицированный NTP-клиент (в настоящее время он просто добавляет 27 секунд и ожидает отметку времени, которая составляет около 1 секунды)
на моем компьютере ArchLinux системное время ведет себя хорошо:
> date
Tue Oct 23 17:10:34 TAI 2018
> date -d @1483228827
Sun Jan 1 00:00:00 UTC 2017
> date -d @1483228826
Sat Dec 31 23:59:60 UTC 2016
> date -d @1483228825
Sat Dec 31 23:59:59 UTC 2016
но: JavaScript не делает:
- тестовая страница
- Использует ли Mozilla/Firefox/Javascript где-то свои собственные файлы информации о зоне?
- Как я могу это исправить?
- Кажется, даже веб-сайты, посвященные времени, не понимают это правильно... Или я что-то упустил?
-arne
1 ответ
JavaScript Date
Объект специально придерживается концепции Unix Time (хотя и с более высокой точностью). Это является частью спецификации POSIX, и поэтому иногда называется "POSIX Time". Он не считает високосные секунды, а предполагает, что каждый день имел ровно 86 400 секунд. Вы можете прочитать об этом в разделе 20.3.1.1 текущей спецификации ECMAScript, в которой говорится:
Время измеряется в ECMAScript в миллисекундах с 1 января 1970 года по Гринвичу. В значениях времени високосные секунды игнорируются. Предполагается, что есть ровно 86 400000 миллисекунд в день.
JavaScript не уникален в этом отношении. Это то, что делают подавляющее большинство других языков, включая Python, Ruby, .NET, типичную реализацию time_t
в Си и многих других.
Потому что вы изменили свою систему, чтобы отслеживать TAI вместо UTC, и в вашей системе есть реализация таблицы дополнительных секунд, что date
команда понимает, то в вашей системе time_t
это не метка времени Unix, а скорее вариант на основе TAI, маскирующийся под метку времени Unix. Просто потому, что date
Команда и другие базовые функции распознают это, но это не значит, что она распространяется на все платформы и среды выполнения на вашем компьютере.
Дело в том, что непредсказуемая природа високосных секунд делает их очень трудными для работы в API. Обычно нельзя передавать временные метки вокруг тех таблиц, которые требуют правильной интерпретации таблиц високосных секунд, и ожидать, что одна система будет интерпретировать их так же, как и другая. Например, пока ваш пример отметки времени 1483228826
является 2017-01-01T00:00:00Z
в вашей системе это будет интерпретироваться как 2017-01-01T00:00:26Z
в системах, основанных на POSIX, или в системах без дополнительных таблиц. Так что они не портативны. Даже в системах с полностью обновленными таблицами невозможно сказать, что эти таблицы будут содержать в будущем (после 6-месячного периода объявления IERS), поэтому я не могу создать будущую временную метку без риска ее возможного изменения.
Чтобы быть ясным - для поддержки високосных секунд в языке программирования, реализация должна делать все возможное, чтобы сделать это, и должна делать компромиссы, которые не всегда приемлемы. Хотя есть исключения, общая позиция состоит в том, чтобы не поддерживать их - не из-за каких-либо подрывных действий или активных контрмер, а потому, что поддерживать их должным образом намного, намного сложнее.
Тем не менее, у вас есть надежда, если вы действительно заботитесь о дополнительных секундах в JavaScript. Вы можете добавить свои мысли к временному предложению TC39 (я один из чемпионов). Это не изменит поведение Date
Объект - это испеченный и был на протяжении десятилетий. Но мы разрабатываем новый набор стандартных объектов для даты и времени в JavaScript и будем рады вашим отзывам и участию. Существует тема, в которой мы рассматривали различные способы, которыми високосные секунды могут быть частью этого в выпуске № 54. На данный момент мы не слишком задумывались о системах на основе TAI. Если это та область, в которой у вас есть опыт, пожалуйста, добавьте свои мысли туда. Имейте в виду, что нам нужно сбалансировать это с общими потребностями сообщества, но мы хотели бы ваши мысли. Спасибо!