Unix time

Unix time passed 1,000,000,000 seconds in 2001-09-09T01:46:40Z. It was celebrated in Copenhagen, Denmark at a party held by DKUUG (at 03:46:40 local time).

Unix time (also known as POSIX time or epoch time) is a system for describing instants in time, defined as the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970,[1][note 1] minus the number of leap seconds that have taken place since then.[1][2][note 2] It is used widely in Unix-like and many other operating systems and file formats. Because the same timestamp can refer to two distinct instants of time around a leap second, it is neither a linear measure of time nor a true representation of UTC.[note 3] Unix time may be checked on most Unix systems by typing date +%s on the command line.

The 32-bit representation of Unix time will end after the completion of 2,147,483,647 (231 - 1) seconds from the beginning (00:00:00 1 January 1970), i.e., on 19 January, 2038 03:14:08 GMT. This is referred to as the "Year 2038 problem" where the 32-bit Unix time will overflow and will take the actual count to negative.

Example: 1502989241 (ISO 8601: 2017-08-17T17:00:41Z)
the Unix time when this page was last generated ()

Definition

Two layers of encoding make up Unix time. The first layer encodes a point in time as a scalar real number which represents the number of seconds that have passed since the beginning of 00:00:00 UTC Thursday 1, January 1970.[3] The second layer encodes that number as a sequence of bits or decimal digits.

As is standard with UTC, this article labels days using the Gregorian calendar, and counts times within each day in hours, minutes, and seconds. Some of the examples also show International Atomic Time (TAI), another time scheme, which uses the same seconds and is displayed in the same format as UTC, but in which every day is exactly 86400 seconds long, gradually losing synchronization with the Earth's rotation at a rate of roughly one second per year.

Encoding time as a number

Unix time is a single signed integer number which increments every second, without requiring the calculations to determine year, month, day of month, hour and minute required for intelligibility to humans. Modern Unix time is based on UTC, which counts time using SI seconds, and breaks up the span of time into days almost always 86,400 seconds long, but due to leap seconds occasionally 86,401 seconds.[note 4] This extra second keeps the days synchronized with the rotation of the Earth, per Universal Time.

The Unix epoch is the time 00:00:00 UTC on 1 January 1970. There is a problem with this definition, in that UTC did not exist in its current form until 1972; this issue is discussed below. For brevity, the remainder of this section uses ISO 8601 date format, in which the Unix epoch is 1970-01-01T00:00:00Z.

The Unix time number is zero at the Unix epoch, and increases by exactly 86,400 per day since the epoch. Thus 2004-09-16T00:00:00Z, 12,677 days after the epoch, is represented by the Unix time number 12,677 × 86,400 = 1095292800. This can be extended backwards from the epoch too, using negative numbers; thus 1957-10-04T00:00:00Z, 4,472 days before the epoch, is represented by the Unix time number −4,472 × 86,400 = −386380800.

Within each day, the Unix time number is calculated as in the preceding paragraph at midnight UTC (00:00:00Z), and increases by exactly 1 per second since midnight. Thus 2004-09-16T17:55:43.54Z, 64,543.54 s since midnight on the day in the example above, is represented by the Unix time number 1095292800 + 64543.54 = 1095357343.54. On dates before the epoch the number still increases, thus becoming less negative, as time moves forward.

Because Unix time is based on the Unix epoch, it is sometimes referred to as "epoch time".

Leap seconds

The above scheme means that on a normal UTC day, which has a duration of 86,400 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:

Unix time across midnight on 17 September 2004
TAI (17 September 2004) UTC (16 to 17 September 2004) Unix time
2004-09-17T00:00:30.75 2004-09-16T23:59:58.75 1 095 379 198.75
2004-09-17T00:00:31.00 2004-09-16T23:59:59.00 1 095 379 199.00
2004-09-17T00:00:31.25 2004-09-16T23:59:59.25 1 095 379 199.25
2004-09-17T00:00:31.50 2004-09-16T23:59:59.50 1 095 379 199.50
2004-09-17T00:00:31.75 2004-09-16T23:59:59.75 1 095 379 199.75
2004-09-17T00:00:32.00 2004-09-17T00:00:00.00 1 095 379 200.00
2004-09-17T00:00:32.25 2004-09-17T00:00:00.25 1 095 379 200.25
2004-09-17T00:00:32.50 2004-09-17T00:00:00.50 1 095 379 200.50
2004-09-17T00:00:32.75 2004-09-17T00:00:00.75 1 095 379 200.75
2004-09-17T00:00:33.00 2004-09-17T00:00:01.00 1 095 379 201.00
2004-09-17T00:00:33.25 2004-09-17T00:00:01.25 1 095 379 201.25

When a leap second occurs, so that the UTC day is not exactly 86,400 seconds long, a discontinuity occurs in the Unix time number. The Unix time number increases by exactly 86,400 each day, regardless of how long the day is. When a leap second is deleted,[note 5] the Unix time number jumps up by 1 where the leap second was deleted, which is the end of the day. When a leap second is inserted,[note 6] the Unix time number increases continuously during the leap second, during which time it is more than 86,400 seconds since the start of the current day, and then jumps back by 1 at the end of the leap second, which is the start of the next day. For example, this is what happened on strictly conforming POSIX.1 systems at the end of 1998:

Unix time across midnight
when a UTC leap second was inserted on 1 January 1999
TAI (1 January 1999) UTC (31 December 1998 to 1 January 1999) Unix time
1999-01-01T00:00:29.75 1998-12-31T23:59:58.75 915 148 798.75
1999-01-01T00:00:30.00 1998-12-31T23:59:59.00 915 148 799.00
1999-01-01T00:00:30.25 1998-12-31T23:59:59.25 915 148 799.25
1999-01-01T00:00:30.50 1998-12-31T23:59:59.50 915 148 799.50
1999-01-01T00:00:30.75 1998-12-31T23:59:59.75 915 148 799.75
1999-01-01T00:00:31.00 1998-12-31T23:59:60.00 915 148 800.00
1999-01-01T00:00:31.25 1998-12-31T23:59:60.25 915 148 800.25
1999-01-01T00:00:31.50 1998-12-31T23:59:60.50 915 148 800.50
1999-01-01T00:00:31.75 1998-12-31T23:59:60.75 915 148 800.75
1999-01-01T00:00:32.00 1999-01-01T00:00:00.00 915 148 800.00
1999-01-01T00:00:32.25 1999-01-01T00:00:00.25 915 148 800.25
1999-01-01T00:00:32.50 1999-01-01T00:00:00.50 915 148 800.50
1999-01-01T00:00:32.75 1999-01-01T00:00:00.75 915 148 800.75
1999-01-01T00:00:33.00 1999-01-01T00:00:01.00 915 148 801.00
1999-01-01T00:00:33.25 1999-01-01T00:00:01.25 915 148 801.25

Observe that when a positive leap second occurs (i.e., when a leap second is inserted) the Unix time numbers repeat themselves. The Unix time number 915148800.50 is ambiguous: it can refer either to the instant in the middle of the leap second, or to the instant one second later, half a second after midnight UTC. In the theoretical case when a negative leap second occurs (i.e., when a leap second is deleted) no ambiguity is caused, but instead there is a range of Unix time numbers that do not refer to any point in time at all.

A Unix clock is often implemented with a different type of positive leap second handling associated with the Network Time Protocol (NTP). 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 UTC by taking the quotient and modulus of the Unix time number, modulo 86400. The quotient is the number of days since the epoch, and the modulus is the number of seconds since midnight UTC on that day.[note 7] 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:

Non-synchronous Mills-style Unix clock
across midnight when a UTC leap second is inserted on 1 January 1999
TAI (1 January 1999) UTC (31 December 1998 to 1 January 1999) state Unix clock
1999-01-01T00:00:29.75 1998-12-31T23:59:58.75 TIME_INS 915 148 798.75
1999-01-01T00:00:30.00 1998-12-31T23:59:59.00 TIME_INS 915 148 799.00
1999-01-01T00:00:30.25 1998-12-31T23:59:59.25 TIME_INS 915 148 799.25
1999-01-01T00:00:30.50 1998-12-31T23:59:59.50 TIME_INS 915 148 799.50
1999-01-01T00:00:30.75 1998-12-31T23:59:59.75 TIME_INS 915 148 799.75
1999-01-01T00:00:31.00 1998-12-31T23:59:60.00 TIME_INS 915 148 800.00
1999-01-01T00:00:31.25 1998-12-31T23:59:60.25 TIME_OOP 915 148 799.25
1999-01-01T00:00:31.50 1998-12-31T23:59:60.50 TIME_OOP 915 148 799.50
1999-01-01T00:00:31.75 1998-12-31T23:59:60.75 TIME_OOP 915 148 799.75
1999-01-01T00:00:32.00 1999-01-01T00:00:00.00 TIME_OOP 915 148 800.00
1999-01-01T00:00:32.25 1999-01-01T00:00:00.25 TIME_WAIT 915 148 800.25
1999-01-01T00:00:32.50 1999-01-01T00:00:00.50 TIME_WAIT 915 148 800.50
1999-01-01T00:00:32.75 1999-01-01T00:00:00.75 TIME_WAIT 915 148 800.75
1999-01-01T00:00:33.00 1999-01-01T00:00:01.00 TIME_WAIT 915 148 801.00
1999-01-01T00:00:33.25 1999-01-01T00:00:01.25 TIME_WAIT 915 148 801.25

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.

TAI-based variant

Another, much rarer, non-conforming variant of Unix time keeping involves encoding TAI rather than UTC; some Linux systems are configured this way.[4] Because TAI has no leap seconds, and every TAI day is exactly 86400 seconds long, this encoding is actually a pure linear count of seconds elapsed since 1970-01-01T00:00:00 TAI. This makes time interval arithmetic much easier. Time values from these systems do not suffer the ambiguity that strictly conforming POSIX systems or NTP-driven systems have.

In these systems it is necessary to consult a table of leap seconds to correctly convert between UTC and the pseudo-Unix-time representation. This resembles the manner in which time zone tables must be consulted to convert to and from civil time; the IANA time zone database includes leap second information, and the sample code available from the same source uses that information to convert between TAI-based time stamps and local time. Conversion also runs into definitional problems prior to the 1972 commencement of the current form of UTC (see section UTC basis below).

This TAI-based system, despite its superficial resemblance, is not Unix time. It encodes times with values that differ by several seconds from the POSIX time values, and does not have the simple mathematical relationship to UTC that is mandated by POSIX.

Representing the number

A Unix time number can be represented in any form capable of representing numbers. In some applications the number is simply represented textually as a string of decimal digits, raising only trivial additional problems. However, certain binary representations of Unix times are particularly significant.

The standard Unix time_t data type that represents a point in time is a signed integer, traditionally of 32 bits (but see below), directly encoding the Unix time number as described in the preceding section. Being 32 bits means that it covers a range of about 136 years in total. The minimum representable time is Friday 1901-12-13, and the maximum representable time is Tuesday 2038-01-19. One second after 03:14:07 UTC 2038-01-19 this representation will overflow. This milestone is anticipated with a mixture of amusement and dread—see year 2038 problem.

In some newer operating systems, time_t has been widened to 64 bits. This expands the times representable by approximately 293 billion years in both directions, which is over twenty times the present age of the universe per direction.

There was originally some controversy over whether the Unix time_t should be signed or unsigned. If unsigned, its range in the future would be doubled, postponing the 32-bit overflow (by 68 years). However, it would then be incapable of representing times prior to the epoch.[note 8] The consensus is for time_t to be signed, and this is the usual practice. The software development platform for version 6 of the QNX operating system has an unsigned 32-bit time_t, though older releases used a signed type.

The POSIX and Open Group Unix specifications include the C standard library, which includes the time types and functions defined in the <time.h> header file. The ISO C standard states that time_t must be an arithmetic type, but does not mandate any specific type or encoding for it. POSIX requires time_t to be an integer type.

Unix has no tradition of directly representing non-integer Unix time numbers as binary fractions. Instead, times with sub-second precision are represented using composite data types that consist of two integers, the first being a time_t (the integral part of the Unix time), and the second being the fractional part of the time number in millionths (in struct timeval) or billionths (in struct timespec). These structures provide a decimal-based fixed-point data format, which is useful for some applications, and trivial to convert for others.

UTC basis

The present form of UTC, with leap seconds, is defined only from 1 January 1972 onwards. Prior to that, since 1 January 1961 there was an older form of UTC in which not only were there occasional time steps, which were by non-integer numbers of seconds, but also the UTC second was slightly longer than the SI second, and periodically changed to continuously approximate the Earth's rotation. Prior to 1961 there was no UTC, and prior to 1958 there was no widespread atomic timekeeping; in these eras, some approximation of GMT (based directly on the Earth's rotation) was used instead of an atomic timescale.

The precise definition of Unix time as an encoding of UTC is only uncontroversial when applied to the present form of UTC. Fortunately, the fact that the Unix epoch predates the start of this form of UTC does not affect its use in this era: the number of days from 1 January 1970 (the Unix epoch) to 1 January 1972 (the start of UTC) is not in question, and the number of days is all that is significant to Unix time.

The meaning of Unix time values below +63 072 000 (i.e., prior to 1 January 1972) is not precisely defined. The basis of such Unix times is best understood to be an unspecified approximation of GMT. Computers of that era rarely had clocks set sufficiently accurately to provide meaningful sub-second timestamps in any case. Unix time is not a suitable way to represent times prior to 1972 in applications requiring sub-second precision; such applications must, at least, define which form of UT or GMT they use.

As of 2009, the possibility of ending the use of leap seconds in civil time is being considered.[5] A likely means to execute this change is to define a new time scale, called "International Time", that initially matches UTC but thereafter has no leap seconds, thus remaining at a constant offset from TAI. If this happens, it is likely that Unix time will be prospectively defined in terms of this new time scale, instead of UTC. Uncertainty about whether this will occur makes prospective Unix time no less predictable than it already is: if UTC were simply to have no further leap seconds the result would be the same.

Command line

In Unix-like operating systems, date is the command which will print or set the current time.[6]

History

The earliest versions of Unix time had a 32-bit integer incrementing at a rate of 60 Hz, which was the rate of the system clock on the hardware of the early Unix systems. The value 60 Hz still appears in some software interfaces as a result. The epoch also differed from the current value. The first edition Unix Programmer's Manual dated 3 November 1971 defines the Unix time as "the time since 00:00:00, 1 January 1971, measured in sixtieths of a second".[7]

The User Manual also commented that "the chronologically-minded user will note that 2**32 sixtieths of a second is only about 2.5 years". Because of this limited range, the epoch was redefined more than once, before the rate was changed to 1 Hz and the epoch was set to its present value of 1 January 1970 00:00:00 UTC. This yielded a range of about 136 years, though with more than half the range in the past (see discussion of signedness above).

As indicated by the definition quoted above, the Unix time scale was originally intended to be a simple linear representation of time elapsed since an epoch. However, there was no consideration of the details of time scales, and it was implicitly assumed that there was a simple linear time scale already available and agreed upon. Indeed, the first edition manual's definition doesn't even specify which time zone is used. Several later problems, including the complexity of the present definition, result from Unix time having been defined gradually by usage rather than fully defined from the outset.

When POSIX.1 was written, the question arose of how to precisely define time_t in the face of leap seconds. The POSIX committee considered whether Unix time should remain, as intended, a linear count of seconds since the epoch, at the expense of complexity in conversions with civil time or a representation of civil time, at the expense of inconsistency around leap seconds. Computer clocks of the era were not sufficiently precisely set to form a precedent one way or the other.

The POSIX committee was swayed by arguments against complexity in the library functions, and firmly defined the Unix time in a simple manner in terms of the elements of UTC time. Unfortunately, this definition was so simple that it didn't even encompass the entire leap year rule of the Gregorian calendar, and would make 2100 a leap year.

The 2001 edition of POSIX.1 rectified the faulty leap year rule in the definition of Unix time, but retained the essential definition of Unix time as an encoding of UTC rather than a linear time scale. Since the mid-1990s, computer clocks have been routinely set with sufficient precision for this to matter, and they have most commonly been set using the UTC-based definition of Unix time. This has resulted in considerable complexity in Unix implementations, and in the Network Time Protocol, to execute steps in the Unix time number whenever leap seconds occur.

Non-Gregorian calendars

The UNIX Epoch (time 0) in non-Gregorian calendars
Calendar Date Additional information
Julian 19-December-1969 Fell on a Thursday
Hebrew 5730-Teveth-23 Embolismic deficient (383-day year)
Islamic 1389-Shawwal-22 Fell on a yawm al-khamis
Persian 1348 Dey 11 Fell on a Panjshanbeh (Thursday)
Mayan 12.17.16.7.5 Lord of the night was G1
Chinese Yi-Chou (Ox), 24, 4667 Year Name was Ji You (Rooster)

Notable events in Unix time

Unix enthusiasts have a history of holding "time_t parties" to celebrate significant values of the Unix time number.[8][9] These are directly analogous to the new year celebrations that occur at the change of year in many calendars. As the use of Unix time has spread, so has the practice of celebrating its milestones. Usually it is time values that are round numbers in decimal that are celebrated, following the Unix convention of viewing time_t values in decimal. Among some groups round binary numbers are also celebrated, such as +230 which occurred at 13:37:04 UTC on Saturday, 10 January 2004.

The events that these celebrate are typically described as "N seconds since the Unix epoch", but this is inaccurate. As discussed above, due to the handling of leap seconds in Unix time, the number of seconds elapsed since the Unix epoch is slightly greater than the Unix time number for times later than the epoch.

In literature and calendrics

Vernor Vinge's novel, A Deepness in the Sky, describes a spacefaring trading civilization thousands of years in the future that still uses the Unix epoch. The "programmer-archaeologist" responsible for finding and maintaining usable code in mature computer systems first believes that the epoch refers to the time when man first walked on the Moon, but then realizes that it is "the 0-second of one of Humankind's first computer operating systems".[25]

Notes

  1. Unix times are defined, but are negative, before 1 January 1970.
  2. Leap seconds are scheduled by the International Earth Rotation and Reference Systems Service and are not predictable.
  3. Unix time cannot unambiguously represent UTC leap seconds (e.g. 31 December 1998 23:59:60), although otherwise the times it represents are UTC.
  4. A day could theoretically be 86,399 seconds long, though this option had never been used as of August 2013.
  5. As of 2016 this has never happened
  6. Leap seconds have been inserted on average once every year and a half.
  7. It is important to ensure that the right type of modulus is being calculated when dealing with times before the epoch, as different algorithms yield values with different values and signs. See Modulo operation for details.
  8. Dennis Ritchie, when asked about this issue, said that he hadn't thought very deeply about it, but was of the opinion that the ability to represent all times within his lifetime would be nice. Ritchie's birth, in 1941, is around Unix time −893 400 000, and his death, in 2011, was before the overflow of 32-bit time_t, so he did indeed achieve his goal.

See also

References

  1. 1 2 "The Open Group Base Specifications Issue 7, section 4.16 Seconds Since the Epoch". The Open Group. Retrieved 22 Jan 2017.
  2. "The Open Group Base Specifications Issue 7, Rationale, section 4.16 Seconds Since the Epoch". The OpenGroup. Retrieved 22 Jan 2017.
  3. "Epoch Converter - Unix Timestamp Converter". Epoch Converter. Retrieved 2017-02-09.
  4. "Time Scales". Network Time Protocol Wiki. Retrieved 2013-01-04.
  5. McCarthy, D. D.; Seidelmann, P. K. (2009). TIME—From Earth Rotation to Atomic Physics. Weinheim: Wiley–VCH Verlag GmbH & Co. KGaA. p. 232. ISBN 978-3-527-40780-4.
  6. date  Commands & Utilities Reference, The Single UNIX Specification, Issue 7 from The Open Group
  7. Unix Programmer's Manual (PDF) (1st ed.). 1971-11-03. Retrieved 2012-03-28. time returns the time since 00:00:00, 1 Jan. 1971, measured in sixtieths of a second.
  8. Tweney, Dylan (12 February 2009). "Unix Lovers to Party Like It's 1234567890". Wired. Retrieved 2013-08-09.
  9. "Slashdot | date +%s Turning 1111111111". Retrieved 2007-07-14.
  10. "Unix time facts & trivia – Unix Time . Info". 100503 unixtime.info
  11. "UNIX Approaches Ripe Old Age of One Billion". Electromagnetic.net. Retrieved 2012-12-06.
  12. "The Risks Digest Volume 21: Issue 69". Catless.ncl.ac.uk. Retrieved 2012-12-06.
  13. nixCraft. "Humor: On Feb, Friday 13, 2009 Unix time Will Be 1234567890". Cyberciti.biz. Retrieved 2012-12-06.
  14. "Google 1234567890 Logo". Google Inc. Retrieved 28 January 2013.
  15. Tweney, Dylan (12 February 2009). "Unix Lovers to Party Like It's 1234567890". Wired News.
  16. Ahmed, Murad (13 February 2009). "At the third stroke, the Unix time will be 1234567890". Times Online.
  17. Krenz, Mark. "Celebrate Epoch Day 15000". Archived from the original on 3 April 2012. Retrieved 28 January 2013.
  18. Kevin Makice (2011-01-26). "Happy Unix Epoch Day 15000". YouTube. Retrieved 2012-12-06.
  19. http://tech.slashdot.org/story/11/01/26/1436203/today-is-epoch-day-15000%5B%5D
  20. "Reddit.com thread". Retrieved 13 May 2014.
  21. "Fun Holiday – Embrace Your Geekness Day". TimeandDate.com. Retrieved 14 July 2017.
  22. "Unix Time Stamp.com". Unixtimestamp.com. Retrieved 2012-12-06.
  23. Spinellis, Diomidis (2006-04-07). "Code Quality: The Open Source Perspective". ISBN 9780321166074.
  24. IDRBT Working Paper No. 9 Y2K38 – Ashutosh Saxena and Sanjay Rawat
  25. Mashey, John R. (27 December 2004). "Languages, Levels, Libraries, and Longevity". Queue. 2 (9): 32–38.

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.