Где високосные секунды в 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 не делает:

-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. Если это та область, в которой у вас есть опыт, пожалуйста, добавьте свои мысли туда. Имейте в виду, что нам нужно сбалансировать это с общими потребностями сообщества, но мы хотели бы ваши мысли. Спасибо!

Другие вопросы по тегам