Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

where are the leap seconds in javascript?

When I use

  • a custom zoneinfo file for TAI or /usr/share/zoneinfo-leaps and
  • a modified NTP client (currently it just adds 27 seconds; and waits for a time stamp that is about 1 second off)

on my ArchLinux box, the system time behaves nicely:

> 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

but: JavaScript does not:

  • test page
  • screenshot

    1. Does Mozilla/Firefox/Javascript use its own zoneinfo files somewhere?
    2. How can i fix it?
    3. Not even websites dedicated to time seem to get it right... Or am i missing something?

-arne

like image 643
RRIDDICC Avatar asked Oct 27 '18 07:10

RRIDDICC


Video Answer


1 Answers

The JavaScript Date object specifically adheres to the concept of Unix Time (albeit with higher precision). This is part of the POSIX specification, and thus is sometimes called "POSIX Time". It does not count leap seconds, but rather assumes every day had exactly 86,400 seconds. You can read about this in section 20.3.1.1 of the current ECMAScript specification, which states:

Time is measured in ECMAScript in milliseconds since 01 January, 1970 UTC. In time values leap seconds are ignored. It is assumed that there are exactly 86,400,000 milliseconds per day.

JavaScript is not unique in this regard. This is what the vast majority of other languages do, including Python, Ruby, .NET, the typical implementation of time_t in C, and many others.

Because you have altered your system to track TAI instead of UTC, and there is an implementation of a leap second table on your system that the date command understands, then on your system time_t isn't a Unix timestamp, but rather a TAI-based variant masquerading as a Unix timestamp. Just because the date command and the other underlying functions recognize this, doesn't mean that carries through to all platforms and runtimes on your machine.

The fact is, that the unpredictable nature of leap seconds makes them very difficult to work with in APIs. One can't generally pass timestamps around that need leap seconds tables to be interpreted correctly, and expect that one system will interpret them the same as another. For example, while your example timestamp 1483228826 is 2017-01-01T00:00:00Z on your system, it would be interpreted as 2017-01-01T00:00:26Z on POSIX based systems, or systems without leap second tables. So they aren't portable. Even on systems that have full updated tables, there's no telling what those tables will contain in the future (beyond the 6-month IERS announcement period), so I can't produce a future timestamp without risk that it may eventually change.

To be clear - to support leap seconds in a programming language, the implementation must go out of its way to do so, and must make tradeoffs that are not always acceptable. Though there are exceptions, the general position is to not support them - not because of any subversion or active countermeasures, but because supporting them properly is much, much harder.

That said, there is hope for you if you really care about leap seconds in JavaScript. You can add your thoughts to TC39 Temporal proposal (of which I am one of the champions). This won't change the behavior of the Date object - that is baked and has been for decades. But we are developing a new set of standard objects for date and time in JavaScript, and would love your feedback and participation. There is a thread where we have been considering various ways that leap seconds could be part of this in issue #54. At the moment, we haven't put much thought into TAI-based systems. If this is an area that you have experience in, please add your thoughts there. Keep in mind we'll need to balance this with the general needs of the community, but we'd like your thoughts. Thanks!

like image 196
Matt Johnson-Pint Avatar answered Oct 28 '22 18:10

Matt Johnson-Pint