where are the leap seconds in javascript?
Asked Answered
G

1

9

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:

-arne

Glarum answered 27/10, 2018 at 7:32 Comment(9)
There is always the language specification, ECMA-262: "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."Bemis
so they implemented special measures that prevent JavaScript to use system zoneinfo? if yes: how can we change that?Glarum
No, they're just not doing anything special to include leap seconds.Defray
but: they took active countermeasures against people like me, who have a system clock that "knows" of those 27 "leaped" seconds... can i turn these countermeasures off somehow? or is my javascript bad?Glarum
On what do you base your assumption of "active countermeasures"? Have you checked what other languages do?Defray
hum... yes... C works fine (or whatever date is written in)... see above... the grey background area...Glarum
You could put a recommendation to the TC39 that controls ECMA-262 and have implementors adopt it. But leap seconds can be ignored unless you're trying to represent them or have a time value that includes them, they aren't needed for general date and time functionality. In this case, you might include a database of values and dates so you can apply them.Bemis
UNIXoid system time can represent leap seconds... so JavaScript just needs to use those functions (e. g. localtime_r (with TZ environment variable) and gmtime_r)... would this be the right place? github.com/tc39/ecma262/issues/newGlarum
discourse.gnome.org/t/…Glarum
D
12

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!

Defray answered 27/10, 2018 at 23:48 Comment(5)
1. an application that runs on multiple computers should use timestamps, that have the same meaning (e. g. (aa) "TAI seconds since the begin of 1970 but not the leap seconds" or (bb) "TAI seconds since the begin of 1970"). 2. (aa) if the system clock does not know of leap seconds (that is easy to find out... one just asks the system to break down 1483228826 with gmtime() and looks at the seconds) then the application could refuse to run or use (transparently to the user) more complicated code.Glarum
1. if someone says, we meet at 1856149396 TAI seconds after the begin of 1970, then it would be "2028-10-26T05:02:49UTC" as far as we can tell today. But due to leap seconds that UTC-time-string might change to "2028-10-26T05:02:39UTC" until the time of the meeting is near. 2. if someone really wants to meet exactly at "2028-10-26T05:02:49UTC", he/she should store that time not as "TAI seconds since some point in time", because UTC just does not support that, since it has anomalies at some (possibly even unknown and unpredictable) points of time.Glarum
i commented on that issue #54 there too: github.com/tc39/proposal-temporal/issues/…Glarum
it seems like GLib deliberately does not interpret the zoneinfo file like glibc... musl has the same... why are they doing that? they try to substitute something good by something that is just wrong...Glarum
Quick update - the linked TC39 Temporal Proposal has explicitly rejected incorporating leap seconds. As of June 2023, it is Stage-3 and mostly finalized.Hottempered

© 2022 - 2024 — McMap. All rights reserved.