Unix time


Unix time is a date and time representation widely used in computing. It measures time by the number of non-leap seconds that have elapsed since 00:00:00 UTC on 1 January 1970, the Unix epoch. For example, at midnight on 1 January 2010, Unix time was 1262304000.
Unix time originated as the system time of Unix operating systems. It has come to be widely used in other computer operating systems, file systems, programming languages, and databases. In modern computing, values are sometimes stored with higher granularity, such as microseconds or nanoseconds.

Definition

Unix time is currently defined as the number of non-leap seconds which have passed since 00:00:00UTC on Thursday, 1 January 1970, which is referred to as the Unix epoch. Unix time is typically encoded as a signed integer.
The Unix time is exactly midnight UTC on 1 January 1970, with Unix time incrementing by 1 for every non-leap second after this. For example, 00:00:00UTC on 1 January 1971 is represented in Unix time as. Negative values, on systems that support them, indicate times before the Unix epoch, with the value decreasing by 1 for every non-leap second before the epoch. For example, 00:00:00UTC on 1 January 1969 is represented in Unix time as. Every day in Unix time consists of exactly seconds.
Unix time is sometimes referred to as Epoch time. This can be misleading since Unix time is not the only time system based on an epoch and the Unix epoch is not the only epoch used by other time systems.

Leap seconds

Unix time differs from both Coordinated Universal Time and International Atomic Time in its handling of leap seconds. UTC includes leap seconds that adjust for the discrepancy between precise time, as measured by atomic clocks, and solar time, relating to the position of the earth in relation to the sun. International Atomic Time, in which every day is precisely seconds long, ignores solar time and gradually loses synchronization with the Earth's rotation at a rate of roughly one second per year. In Unix time, every day contains exactly seconds. Each leap second uses the timestamp of a second that immediately precedes or follows it.
On a normal UTC day, which has a duration of seconds, the Unix time number changes in a continuous manner across midnight. For example, at the end of the day used in the examples above, the time representations progress as follows:
TAI UTC Unix time
2004-09-17T00:00:30.752004-09-16T23:59:58.75
2004-09-17T00:00:31.002004-09-16T23:59:59.00
2004-09-17T00:00:31.252004-09-16T23:59:59.25
2004-09-17T00:00:31.502004-09-16T23:59:59.50
2004-09-17T00:00:31.752004-09-16T23:59:59.75
2004-09-17T00:00:32.002004-09-17T00:00:00.00
2004-09-17T00:00:32.252004-09-17T00:00:00.25
2004-09-17T00:00:32.502004-09-17T00:00:00.50
2004-09-17T00:00:32.752004-09-17T00:00:00.75
2004-09-17T00:00:33.002004-09-17T00:00:01.00
2004-09-17T00:00:33.252004-09-17T00:00:01.25

When a leap second occurs, the UTC day is not exactly seconds long and the Unix time number experiences a discontinuity. Leap seconds may be positive or negative. No negative leap second has ever been declared, but if one were to be, then at the end of a day with a negative leap second, the Unix time number would jump up by 1 to the start of the next day. During a positive leap second at the end of a day, which occurs about every year and a half on average, the Unix time number increases continuously into the next day during the leap second and then at the end of the leap second jumps back by 1. For example, this is what happened on strictly conforming POSIX.1 systems at the end of 1998:
TAI UTC Unix time
1999-01-01T00:00:29.751998-12-31T23:59:58.75
1999-01-01T00:00:30.001998-12-31T23:59:59.00
1999-01-01T00:00:30.251998-12-31T23:59:59.25
1999-01-01T00:00:30.501998-12-31T23:59:59.50
1999-01-01T00:00:30.751998-12-31T23:59:59.75
1999-01-01T00:00:31.001998-12-31T23:59:60.00
1999-01-01T00:00:31.251998-12-31T23:59:60.25
1999-01-01T00:00:31.501998-12-31T23:59:60.50
1999-01-01T00:00:31.751998-12-31T23:59:60.75
1999-01-01T00:00:32.001999-01-01T00:00:00.00
1999-01-01T00:00:32.251999-01-01T00:00:00.25
1999-01-01T00:00:32.501999-01-01T00:00:00.50
1999-01-01T00:00:32.751999-01-01T00:00:00.75
1999-01-01T00:00:33.001999-01-01T00:00:01.00
1999-01-01T00:00:33.251999-01-01T00:00:01.25

Unix time numbers are repeated in the second immediately following a positive leap second. The Unix time number is thus ambiguous: it can refer either to start of the leap second or the end of it, one second later. In the theoretical case when a negative leap second occurs, no ambiguity is caused, but instead there is a range of Unix time numbers that do not refer to any point in UTC time at all.
A Unix clock is often implemented with a different type of positive leap second handling associated with the Network Time Protocol. This yields a system that does not conform to the POSIX standard. See the section below concerning NTP for details.
When dealing with periods that do not encompass a UTC leap second, the difference between two Unix time numbers is equal to the duration in seconds of the period between the corresponding points in time. This is a common computational technique. However, where leap seconds occur, such calculations give the wrong answer. In applications where this level of accuracy is required, it is necessary to consult a table of leap seconds when dealing with Unix times, and it is often preferable to use a different time encoding that does not suffer from this problem.
A Unix time number is easily converted back into a UTC time by taking the quotient and modulus of the Unix time number, modulo. The quotient is the number of days since the epoch, and the modulus is the number of seconds since midnight UTC on that day. If given a Unix time number that is ambiguous due to a positive leap second, this algorithm interprets it as the time just after midnight. It never generates a time that is during a leap second. If given a Unix time number that is invalid due to a negative leap second, it generates an equally invalid UTC time. If these conditions are significant, it is necessary to consult a table of leap seconds to detect them.

Non-synchronous Network Time Protocol-based variant

Commonly a Mills-style Unix clock is implemented with leap second handling not synchronous with the change of the Unix time number. The time number initially decreases where a leap should have occurred, and then it leaps to the correct time 1 second after the leap. This makes implementation easier, and is described by Mills' paper. This is what happens across a positive leap second:
TAI UTC StateUnix clock
1999-01-01T00:00:29.751998-12-31T23:59:58.75TIME_INS
1999-01-01T00:00:30.001998-12-31T23:59:59.00TIME_INS
1999-01-01T00:00:30.251998-12-31T23:59:59.25TIME_INS
1999-01-01T00:00:30.501998-12-31T23:59:59.50TIME_INS
1999-01-01T00:00:30.751998-12-31T23:59:59.75TIME_INS
1999-01-01T00:00:31.001998-12-31T23:59:60.00TIME_INS
1999-01-01T00:00:31.251998-12-31T23:59:60.25TIME_OOP
1999-01-01T00:00:31.501998-12-31T23:59:60.50TIME_OOP
1999-01-01T00:00:31.751998-12-31T23:59:60.75TIME_OOP
1999-01-01T00:00:32.001999-01-01T00:00:00.00TIME_OOP
1999-01-01T00:00:32.251999-01-01T00:00:00.25TIME_WAIT
1999-01-01T00:00:32.501999-01-01T00:00:00.50TIME_WAIT
1999-01-01T00:00:32.751999-01-01T00:00:00.75TIME_WAIT
1999-01-01T00:00:33.001999-01-01T00:00:01.00TIME_WAIT
1999-01-01T00:00:33.251999-01-01T00:00:01.25TIME_WAIT

This can be decoded properly by paying attention to the leap second state variable, which unambiguously indicates whether the leap has been performed yet. The state variable change is synchronous with the leap.
A similar situation arises with a negative leap second, where the second that is skipped is slightly too late. Very briefly the system shows a nominally impossible time number, but this can be detected by the TIME_DEL state and corrected.
In this type of system the Unix time number violates POSIX around both types of leap second. Collecting the leap second state variable along with the time number allows for unambiguous decoding, so the correct POSIX time number can be generated if desired, or the full UTC time can be stored in a more suitable format.
The decoding logic required to cope with this style of Unix clock would also correctly decode a hypothetical POSIX-conforming clock using the same interface. This would be achieved by indicating the TIME_INS state during the entirety of an inserted leap second, then indicating TIME_WAIT during the entirety of the following second while repeating the seconds count. This requires synchronous leap second handling. This is probably the best way to express UTC time in Unix clock form, via a Unix interface, when the underlying clock is fundamentally untroubled by leap seconds.