Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Unix time
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Definition == Unix time is currently defined as the number of non-leap seconds which have passed since 00:00:00{{nbsp}}UTC on Thursday, 1 January 1970, which is referred to as the ''Unix [[epoch (computing)|epoch]]''.<ref name="single-unix-spec-4.16" /> Unix time is typically encoded as a [[signed integer]]. The Unix time {{val|0}} 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:00{{nbsp}}UTC on 1 January 1971 is represented in Unix time as {{val|31536000}}. 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:00{{nbsp}}UTC on 1 January 1969 is represented in Unix time as {{val|-31536000}}. Every day in Unix time consists of exactly {{val|86400}} 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.<ref>{{cite web |url=https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime |title=FILETIME structure (minwinbase.h) |website=[[Microsoft Docs]]|date=2 April 2021 }}</ref> === Leap seconds === Unix time differs from both [[Coordinated Universal Time]] (UTC) and [[International Atomic Time]] (TAI) in its handling of [[leap second]]s. 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]] (TAI), in which every day is precisely {{val|86400}} 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 {{val|86400}} seconds. Each leap second uses the [[timestamp]] of a second that immediately precedes or follows it.<ref name="single-unix-spec-4.16"/> On a normal UTC day, which has a duration of {{val|86400}} seconds, the Unix time number changes in a [[continuous function|continuous]] manner across midnight. For example, at the end of the day used in the examples above, the time representations progress as follows: {| class="wikitable" style="text-align: center;" |+ Unix time across midnight into 17 September 2004 (without leap seconds) |- ! TAI (17 September 2004) ! UTC (16 to 17 September 2004) ! Unix time |- | 2004-09-17T00:00:30.75 | 2004-09-16T23:59:58.75 | style="text-align: right;" | {{val|1095379198.75}} |- | 2004-09-17T00:00:31.00 | 2004-09-16T23:59:59.00 | style="text-align: right;" | {{val|1095379199.00}} |- | 2004-09-17T00:00:31.25 | 2004-09-16T23:59:59.25 | style="text-align: right;" | {{val|1095379199.25}} |- | 2004-09-17T00:00:31.50 | 2004-09-16T23:59:59.50 | style="text-align: right;" | {{val|1095379199.50}} |- ! 2004-09-17T00:00:31.75 ! 2004-09-16T23:59:59.75 ! style="text-align: right;" | {{val|1095379199.75}} |- ! 2004-09-17T00:00:32.00 ! 2004-09-17T00:00:00.00 ! style="text-align: right;" | {{val|1095379200.00}} |- | 2004-09-17T00:00:32.25 | 2004-09-17T00:00:00.25 | style="text-align: right;" | {{val|1095379200.25}} |- | 2004-09-17T00:00:32.50 | 2004-09-17T00:00:00.50 | style="text-align: right;" | {{val|1095379200.50}} |- | 2004-09-17T00:00:32.75 | 2004-09-17T00:00:00.75 | style="text-align: right;" | {{val|1095379200.75}} |- | 2004-09-17T00:00:33.00 | 2004-09-17T00:00:01.00 | style="text-align: right;" | {{val|1095379201.00}} |- | 2004-09-17T00:00:33.25 | 2004-09-17T00:00:01.25 | style="text-align: right;" | {{val|1095379201.25}} |} When a [[leap second]] occurs, the UTC day is not exactly {{val|86400}} seconds long and the Unix time number (which always increases by exactly {{val|86400}} each day) experiences a [[discontinuity (mathematics)|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 (returning to the start of the next day). For example, this is what happened on strictly conforming [[POSIX.1]] systems at the end of 1998: {| class="wikitable" id="leapsecondinserted" style="text-align: center;" |+ Unix time across midnight into 1 January 1999 (positive leap second) |- ! 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 | style="text-align: right;" | {{val|915148798.75}} |- | 1999-01-01T00:00:30.00 | 1998-12-31T23:59:59.00 | style="text-align: right;" | {{val|915148799.00}} |- | 1999-01-01T00:00:30.25 | 1998-12-31T23:59:59.25 | style="text-align: right;" | {{val|915148799.25}} |- | 1999-01-01T00:00:30.50 | 1998-12-31T23:59:59.50 | style="text-align: right;" | {{val|915148799.50}} |- | 1999-01-01T00:00:30.75 | 1998-12-31T23:59:59.75 | style="text-align: right;" | {{val|915148799.75}} |- | 1999-01-01T00:00:31.00 ! 1998-12-31T23:59:60.00 | style="text-align: right;" | {{val|915148800.00}} |- | 1999-01-01T00:00:31.25 ! 1998-12-31T23:59:60.25 | style="text-align: right;" | {{val|915148800.25}} |- | 1999-01-01T00:00:31.50 ! 1998-12-31T23:59:60.50 | style="text-align: right;" | {{val|915148800.50}} |- ! 1999-01-01T00:00:31.75 ! 1998-12-31T23:59:60.75 ! style="text-align: right;" | {{val|915148800.75}} |- ! 1999-01-01T00:00:32.00 ! 1999-01-01T00:00:00.00 ! style="text-align: right;" | {{val|915148800.00}} |- | 1999-01-01T00:00:32.25 | 1999-01-01T00:00:00.25 | style="text-align: right;" | {{val|915148800.25}} |- | 1999-01-01T00:00:32.50 | 1999-01-01T00:00:00.50 | style="text-align: right;" | {{val|915148800.50}} |- | 1999-01-01T00:00:32.75 | 1999-01-01T00:00:00.75 | style="text-align: right;" | {{val|915148800.75}} |- | 1999-01-01T00:00:33.00 | 1999-01-01T00:00:01.00 | style="text-align: right;" | {{val|915148801.00}} |- | 1999-01-01T00:00:33.25 | 1999-01-01T00:00:01.25 | style="text-align: right;" | {{val|915148801.25}} |} Unix time numbers are repeated in the second immediately following a positive leap second. The Unix time number {{val|1483228800}} is thus ambiguous: it can refer either to start of the leap second (2016-12-31 23:59:60) or the end of it, one second later (2017-01-01 00:00:00). 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]] (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 a UTC time by taking the quotient and modulus of the Unix time number, modulo {{val|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. 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 [[David L. Mills|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.<ref name="eeci_TheN">{{Cite web | title = The NTP Timescale and Leap Seconds | last = Mills | first = David L. | work = eecis.udel.edu | date = 12 May 2012 | access-date = 21 August 2017 | url = https://www.eecis.udel.edu/~mills/leap.html | archive-date = 15 May 2012 | archive-url = https://web.archive.org/web/20120515005611/http://www.eecis.udel.edu/~mills/leap.html | url-status = live }}</ref> This is what happens across a positive leap second: {| class="wikitable" style="text-align: center;" |+ Non-synchronous Mills-style Unix clock<br>across midnight into 1 January 1999 (positive leap second) |- ! 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 | style="text-align: right;" | {{val|915148798.75}} |- | 1999-01-01T00:00:30.00 | 1998-12-31T23:59:59.00 | TIME_INS | style="text-align: right;" | {{val|915148799.00}} |- | 1999-01-01T00:00:30.25 | 1998-12-31T23:59:59.25 | TIME_INS | style="text-align: right;" | {{val|915148799.25}} |- | 1999-01-01T00:00:30.50 | 1998-12-31T23:59:59.50 | TIME_INS | style="text-align: right;" | {{val|915148799.50}} |- | 1999-01-01T00:00:30.75 | 1998-12-31T23:59:59.75 | TIME_INS | style="text-align: right;" | {{val|915148799.75}} |- ! 1999-01-01T00:00:31.00 ! 1998-12-31T23:59:60.00 ! TIME_INS ! style="text-align: right;" | {{val|915148800.00}} |- ! 1999-01-01T00:00:31.25 ! 1998-12-31T23:59:60.25 ! TIME_OOP ! style="text-align: right;" | {{val|915148799.25}} |- | 1999-01-01T00:00:31.50 | 1998-12-31T23:59:60.50 | TIME_OOP | style="text-align: right;" | {{val|915148799.50}} |- ! 1999-01-01T00:00:31.75 ! 1998-12-31T23:59:60.75 ! TIME_OOP ! style="text-align: right;" | {{val|915148799.75}} |- ! 1999-01-01T00:00:32.00 ! 1999-01-01T00:00:00.00 ! TIME_OOP ! style="text-align: right;" | {{val|915148800.00}} |- | 1999-01-01T00:00:32.25 | 1999-01-01T00:00:00.25 | TIME_WAIT | style="text-align: right;" | {{val|915148800.25}} |- | 1999-01-01T00:00:32.50 | 1999-01-01T00:00:00.50 | TIME_WAIT | style="text-align: right;" | {{val|915148800.50}} |- | 1999-01-01T00:00:32.75 | 1999-01-01T00:00:00.75 | TIME_WAIT | style="text-align: right;" | {{val|915148800.75}} |- | 1999-01-01T00:00:33.00 | 1999-01-01T00:00:01.00 | TIME_WAIT | style="text-align: right;" | {{val|915148801.00}} |- | 1999-01-01T00:00:33.25 | 1999-01-01T00:00:01.25 | TIME_WAIT | style="text-align: right;" | {{val|915148801.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. ==== Variant that counts leap seconds ==== Another, much rarer, non-conforming variant of Unix time keeping involves incrementing the value for all seconds, including leap seconds;<ref>{{cite web|url=https://www.iana.org/time-zones/repository/tz-link.html#precision|work=Sources for time zone and daylight saving time data|title=Precision timekeeping|quote=The tz code and data support leap seconds via an optional "right" configuration where a computer's internal time_t integer clock counts every TAI second, as opposed to the default "posix" configuration where the internal clock ignores leap seconds. The two configurations agree for timestamps starting with 1972-01-01 00:00:00 UTC (time_t 63 072 000) and diverge for timestamps starting with time_t 78 796 800, which corresponds to the first leap second 1972-06-30 23:59:60 UTC in the "right" configuration, and to 1972-07-01 00:00:00 UTC in the "posix" configuration.|access-date=30 May 2022|archive-date=16 October 2017|archive-url=https://web.archive.org/web/20171016230241/http://www.iana.org/time-zones/repository/tz-link.html#precision|url-status=live}}</ref> some Linux systems are configured this way.<ref name="ntp-time-scales">{{cite web|title=Time Scales|url=https://support.ntp.org/bin/view/Support/TimeScales|work=Network Time Protocol Wiki|date=24 July 2019|access-date=12 January 2020|archive-date=12 January 2020|archive-url=https://web.archive.org/web/20200112103701/https://support.ntp.org/bin/view/Support/TimeScales|url-status=live}}</ref> Time kept in this fashion is sometimes referred to as "TAI" (although timestamps can be converted to UTC if the value corresponds to a time when the difference between TAI and UTC is known), as opposed to "UTC" (although not all UTC time values have a unique reference in systems that do not count leap seconds).<ref name="ntp-time-scales" /> 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:10{{nbsp}}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 timestamps and local time. Conversion also runs into definitional problems prior to the 1972 commencement of the current form of UTC (see section [[#UTC basis|UTC basis]] below). This system, despite its superficial resemblance, is not Unix time. It encodes times with values that differ by several seconds from the POSIX time values. A version of this system, in which the epoch was 1970-01-01T00:00:00{{nbsp}}TAI rather than 1970-01-01T00:00:10{{nbsp}}TAI, was proposed for inclusion in ISO C's [[C date and time functions|{{code|time.h}}]], but only the UTC part was accepted in 2011.<ref>{{cite web |author=Markus Kuhn |title=Modernized API for ISO C |url=https://www.cl.cam.ac.uk/~mgk25/time/c/ |website=www.cl.cam.ac.uk |access-date=31 August 2020 |archive-date=26 September 2020 |archive-url=https://web.archive.org/web/20200926224028/https://www.cl.cam.ac.uk/~mgk25/time/c/ |url-status=live }}</ref> A {{code|tai_clock}} does, however, exist in C++20. === 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 Unix <!-- time_t meaning time type is a C type name. DO NOT REPLACE «time_t» WITH «time t»!!! --><code>[[time_t]]</code><!-- DO NOT REPLACE «time_t» WITH «time t»!!! --> data type that represents a point in time is, on many platforms, a [[Integer (computer science)|signed integer]], traditionally of 32{{nbsp}}[[bit]]s (but [[#Range of representable times|see below]]), directly encoding the Unix time number as described in the preceding section. A signed 32-bit value covers about 68 years before and after the 1970-01-01 epoch. The minimum representable date is Friday 1901-12-13, and the maximum representable date is Tuesday 2038-01-19. One second after 2038-01-19T03:14:07Z this representation will [[arithmetic overflow|overflow]] in what is known as the [[year 2038 problem]]. [[UUID]]v7 encodes the Unix epoch timestamp (in milliseconds) in an unsigned 48-bit field. This representation is valid until the year 10889 AD.<ref> {{IETF RFC|9562}} </ref> In some newer operating systems, <code>time_t</code> has been widened to 64 bits. This expands the times representable to about {{tooltip|1={{round|2^63/365.2422/24/3600/10^9|1}} billion years|2=More precisely, 292277264695 years}}<!-- note:including {{round}} inside {{tooltip}} doesn't work when the resulting number results has an exponent --> in both directions, which is over twenty times the present [[age of the universe]]. There was originally some controversy over whether the Unix <code>time_t</code> 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. The consensus is for <code>time_t</code> 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 <code>time_t</code>, 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|<code><time.h></code>]] header file. The ISO C standard states that <code>time_t</code> must be an arithmetic type, but does not mandate any specific type or encoding for it. POSIX requires <code>time_t</code> to be an integer type, but does not mandate that it be signed or unsigned. 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 type]]s that consist of two integers, the first being a <code>time_t</code> (the integral part of the Unix time), and the second being the fractional part of the time number in millionths (in <code>struct timeval</code>) or billionths (in <code>struct timespec</code>).<ref>{{cite web |title=timespec |url=https://netbsd.gw.com/cgi-bin/man-cgi?timespec |website=NetBSD Manual Pages |access-date=5 July 2019 |date=12 April 2011 |archive-date=10 August 2019 |archive-url=https://web.archive.org/web/20190810060329/https://netbsd.gw.com/cgi-bin/man-cgi?timespec |url-status=live }}</ref><ref>{{cite web |title=time.h(0P) |url=http://man7.org/linux/man-pages/man0/time.h.0p.html |website=Linux manual page |access-date=5 July 2019 |archive-date=27 June 2019 |archive-url=https://web.archive.org/web/20190627152007/http://man7.org/linux/man-pages/man0/time.h.0p.html |url-status=live }}</ref> These structures provide a [[decimal]]-based [[Fixed-point arithmetic|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 starting from 1 January 1972. 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 clock|atomic timekeeping]]; in these eras, some approximation of [[GMT]] (based directly on the Earth's rotation) was used instead of an atomic timescale.{{Citation needed|date=May 2012}} The precise definition of Unix time as an encoding of UTC is only uncontroversial when applied to the present form of UTC. The Unix epoch predating 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 {{val|+63072000}} (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 UTC. 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.<ref>{{Cite book | last1=McCarthy | first1=D. D. | last2=Seidelmann | first2=P. K. | author-link1=Dennis McCarthy (scientist) | date=2009 | title=TIME—From Earth Rotation to Atomic Physics | page=232 | publisher=Wiley–VCH Verlag GmbH & Co. KGaA | location=Weinheim | isbn=978-3-527-40780-4 }}</ref> A likely means to execute this change is to define a new time scale, called ''International Time''{{Citation needed|date=February 2023}}, 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.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)