12

I know that the Unix timestamp is defined as the number of seconds passed since 1970-01-01 00:00:00Z. However, I could not find a clear source that gives this definition. I've also read various different statements about the relationship between UTC and the Unix Timestamp in regards to leap seconds.

This wikipedia page contains a list of all leap seconds. The first one is

1972-06-30 23:59:60

Statements about Unix timestamps

As for "all modern computer systems", Unix time is completely ignorant about anything except seconds.

Source: HackerNews, brazzy

UNIX time tracks UTC instead of TAI meaning it "corrects" for leap seconds. As a result, UNIX time is not "the number of seconds since epoch" but "86400 * (number of whole days since epoch) + (number of seconds since midnight)", and UNIX time will go forwards (never so far) and backwards on leap seconds (a second will repeat in most implementations as the day goes from 23:59:60 to 00:00:00, as they have the same timestamp).

Source: Hacker News, masklinn

I've also read (but I can't find it again - somewhere on Stack Overflow) that Unix Timestamps assume each day has exactly 24*60*60 seconds. The poster implied that days are still somehow kept synchronously while the leap seconds simply "slows down" the real second. Hence a "unix timestamp second" might not be a SI second.

Possible answers

I can see three possible answers:

A1: Unix Timestamps track SI seconds since 1970-01-01 00:00:00Z. This means they are 27 seconds off from the UTC.

A2: Unix Timestamps track "passed seconds in TAI". This means a library that converts Unix timestamps to UTC has to deal with leap seconds.

A3: Unix Timestamps track "passed seconds in UTC". This means that a difference between two Unix timestamps of 1 might be 1 SI-second in most cases, but not in all.

Please add a source to your answer.

Python

Pythons datetime seems not to be aware of leap seconds (?).

>>> import datetime
>>> a = datetime.datetime(1972, 6, 30, 23, 59, 59)
>>> b = datetime.datetime(1972, 7, 1, 0, 0, 0)
>>> b-a
datetime.timedelta(0, 1)

and the time module seems to map the actual leap second on the second before:

>>> import time
>>> t3 = time.mktime((1972, 6, 30, 23, 59, 59, -1, -1, -1))
>>> t4 = time.mktime((1972, 7, 1, 0, 0, 0, -1, -1, -1))
>>> t4 - t3
1.0
>>> t4 = time.mktime((1972, 6, 30, 23, 59, 60, -1, -1, -1))
>>> t4 - t3
1.0

This impression is supported by issue23574.

jwodder
  • 54,758
  • 12
  • 108
  • 124
Martin Thoma
  • 124,992
  • 159
  • 614
  • 958

2 Answers2

3

A.4.16 Seconds Since the Epoch

Coordinated Universal Time (UTC) includes leap seconds. However, in POSIX time (seconds since the Epoch), leap seconds are ignored (not applied) to provide an easy and compatible method of computing time differences. Broken-down POSIX time is therefore not necessarily UTC, despite its appearance. [...]

Most systems' notion of "time" is that of a continuously increasing value, so this value should increase even during leap seconds. However, not only do most systems not keep track of leap seconds, but most systems are probably not synchronized to any standard time reference. Therefore, it is inappropriate to require that a time represented as seconds since the Epoch precisely represent the number of seconds between the referenced time and the Epoch.

It is sufficient to require that applications be allowed to treat this time as if it represented the number of seconds between the referenced time and the Epoch. It is the responsibility of the vendor of the system, and the administrator of the system, to ensure that this value represents the number of seconds between the referenced time and the Epoch as closely as necessary for the application being run on that system.

Source: http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16

Community
  • 1
  • 1
enveeed
  • 197
  • 2
  • 7
0

Unix time tracks the SI seconds elapsed since 1970-01-01 00:00:00 UTC minus the leap seconds of UTC. Positive leap seconds are not counted and negative leap seconds are counted twice. In other words, it counts as if each day lasted 86,400 SI seconds, so a Unix time which is a multiple of 86,400 corresponds to midnight UTC.

Midnight transition without leap second (UTC day lasts 86,400 SI seconds):

UTC       Second #  Unix time (mod 86,400)
--------  --------  ----------------------
23:59:58  86,398th  86,398
23:59:59  86,399th  86,399
00:00:00  86,400th  86,400

Midnight transition with positive leap second (UTC day lasts 86,401 SI seconds); it has happened on 27 days so far:

UTC       Second #  Unix time (mod 86,400)
--------  --------  ----------------------
23:59:59  86,399th  86,399
23:59:60  86,400th  86,399 <- positive leap second: not counted in Unix time
00:00:00  86,401th  86,400

Midnight transition with negative leap second (UTC day lasts 86,399 SI seconds); it has never happened so far:

UTC       Second #  Unix time (mod 86,400)
--------  --------  ----------------------
23:59:57  86,397th  86,397
23:59:58  86,398th  86,398 86,399 <- negative leap second: counted twice in
00:00:00  86,399th  86,400           Unix time

See this this answer for additional information.

Géry Ogam
  • 6,336
  • 4
  • 38
  • 67
  • 1
    The first negative leap second might happen soon! June 29, 2022 was the shortest day ever recorded. – Andrew Aug 10 '22 at 12:33