A few days ago, representatives from across the world voted to abolish leap seconds from coordinated universal time, the world’s most popular time standard, on which all timezones are based (abbreviated as UTC). As it is right now, a leap second is inserted every once in a while to make sure that UTC stays synchronized with the rotation of the Earth. The universe is really quite complex, and so the exact rotation of the Earth is irregular and unpredictable to us. As a result, leap seconds are also irregular and unpredictable. Leap seconds are based upon satellite measurements and announced by the organization IERS about six months before their insertion into UTC. On average, a leap second is inserted approximately every year and a half, but this can vary by a wide margin.

Another important time standard is international atomic time (abbreviated TAI, from the French name “temps atomique international”), a standard which is not kept in sync with the rotation of the Earth and does not have leap seconds. The difference between TAI and UTC is by definition an integer number of seconds. Since 1958 the time in TAI has drifted apart from the time based on the rotation of the Earth, leading to a difference of 37 seconds in 2022.

The decision to get rid of leap seconds was made because of the havoc that leap seconds cause on computer systems. To put it simply, engineers expect that the timestamp of the next second is equal to the current timestamp plus one (that is, t_next == t + 1), but because of leap seconds, that is not true. The timestamp of the next second can be the same as the current timestamp, or it could hypothetically even be the current timestamp plus two (“hypothetically” because a leap second in this direction has not yet happened). The fact that these assumptions aren’t actually true breaks a lot of code, and in turn a lot of systems.

However, the abolishment of leap seconds doesn’t mean that the problem is now solved. It still has to be decided how UTC is going to stay synchronized with the rotation of the Earth after the leap second goes away, and also whether UTC is going to stay synchronized at all. Both solutions have their downsides: If UTC becomes a linear system with no discontinuities, then it will eventually be significantly out-of-sync with the rotation of the Earth, just like TAI. On the other hand, if the leap second is replaced by a leap minute or a leap hour, then the current problems will still persist, and albeit less frequently, such problems will have a much bigger effect.

The point I intend to make in this article is as follows: leap seconds were not a mistake. Leap seconds in UTC are fine, because UTC was not primarily meant for engineering purposes. The mistake was, instead, to base Unix time and other computer timestamp formats on UTC instead of a strictly linear time scale. The fact that Unix time is not a linear time scale takes away a lot of mathematical properties that are crucial for its application in computers. I’ll show this in section 3. In the last section, I will discuss a proposal for changes to Unix time that would hopefully resolve this problem once and for all, completely independent of whatever might happen to UTC in the future and ideally without too much work. First, let’s talk about Unix time.

Unix time

The simplified definition of Unix time is that Unix time counts the amount of seconds that have passed since the first of January 1970 (which is referred to as “the epoch”, similar to the first of January of 1 AD being the epoch of the Gregorian calendar). This is of course not the complete definition, since it does not take leap seconds into consideration. The exact way Unix time handles leap seconds* is complex and an unnecessary detail for this article, but it will suffice to say that (i) whenever a positive leap second occurs, a timestamp is used twice, and (ii) if a negative leap second were to occur, a timestamp is skipped.

Besides Unix time, there is also TAI Unix time, which has no leap seconds and therefore truly counts the amount of seconds since its epoch. The epoch of TAI Unix time is January 1970 00:00:10 TAI, so ten seconds past midnight. This epoch is exactly the same moment in time as the epoch of Unix time, despite looking a little different, because the difference between UTC and TAI was ten seconds in 1970. TAI Unix time is strictly linear and has a lot of favourable mathematical properties, but is not very popular.

I’d quickly like to note that TAI Unix time is not Unix time and that TAI Unix time should always be clearly distinguished from normal Unix time. I think it’s best to compare it to bread and bread sticks. They’re both bread, they both have “bread” in the name, but when you ask a baker for bread, you don’t expect to be given bread sticks. The same applies with Unix time and TAI Unix time: When you ask for Unix time, you don’t expect to be given TAI Unix time.

I don’t mean to spoil the proposal at the end of the article, but if you’re guessing that it’s “just start using TAI Unix time”, then you’re only partially correct.

Comparison of timestamping techniques

In the table below, I compare the properties of linear timestamping techniques such as TAI Unix time to timestamping techniques with leap seconds such as Unix time. Most of the time I only mention leap seconds, but the same applies for leap minutes, leap hours or any other leaps.


Linear timestamping
such as TAI Unix time
Timestamping with leap seconds (or leap minutes, or leap hours)
such as Unix time
Determining the timestamp of t + 1 s
Easy Very difficult
Because the next second might be a leap second, this gets quite difficult. At the very minimum, the computer must get external information once every six months to ensure that it's aware of the next leap second.
Determining the timestamp of t + 100000000 s Easy Impossible
Leap seconds of the far future are not yet known, so this cannot be calculated, only estimated.
Determining the difference between two timestamps in seconds Easy
Just subtract.
Somewhat difficult
Requires a look-up into a leap second table.
Determining the date or the time of day Difficult
We usually want to know the time in some timezone derived from UTC, and not in TAI. The timestamp must be converted to UTC first and therefore an up-to-date leap second table is required. For efficiency, it's possible to skip the table look-up for all timestamps close to the present by keeping a few variables cached.
Easy
You can get the amount of days that have passed since the epoch by dividing a timestamp by the amount of seconds in a day (using integer division), or take the remainder of that division to get the amount of seconds since the start of the day. Those two variables can then be used to determine the date and the time of day.
Determining the timestamp of 2500 AD, January 1, 00:00:00 UTC or any UTC-based date in the far future Impossible
The date needs to be converted from UTC to TAI, which requires a leap second table, but leap seconds in the far future are not yet known.
Easy
Ambiguous No Yes
A timestamp of a positive leap second can refer to two moments in time.
Has invalid values No Yes
For each negative leap second there is an integer that is not a valid timestamp.

Especially the first point, about determining t + 1s, and the third point, about determining the difference, are hugely important for software internals. However, as you can see in the table, UTC-based timestamps do still have their applications. After all, UTC is what users want to see.

I conclude that linear timestamping is ideal for software internals, such as storing file modification dates, networking and any kind of mathematics using timestamps, but when showing the time to the user, it should be converted to UTC. Furthermore, when the user wants the computer to remember a date in the future, such as in the case of calendar software, UTC-based timestamps are slightly better. This is because future leap seconds are not yet known, so you can only estimate the TAI-based timestamp of a UTC-based date in the far future. That estimate is likely to be a few seconds off, which can sometimes be significant (for example when code is supposed to make something happen exactly at midnight of new year’s eve, you would not want to be a few seconds off).

However, “just switching to TAI Unix time” would have some Y2K-esque consequences. There is a difference of 27 seconds between Unix time and TAI Unix time, and that’s also a leap in the direction that leap seconds have never gone before. Considering this, “just switching to TAI Unix time” without causing too many big incidents becomes a monumental task.

Proposal for changes to Unix time

To solve these issues without too much pain, I propose that Unix time be split into three in the POSIX standard:

  • UTC Unix time, which will keep tracking UTC wherever it might go in the future.
  • TAI+C Unix time, which is just TAI Unix time offset by some constant amount of seconds. The constant C should be chosen so that the TAI+C Unix time will line up exactly with Unix time at the moment the transition is made from the current definition of Unix time to this proposed definition of Unix time.
  • Legacy Unix time, which interpolates between UTC Unix time and TAI+C Unix time. Timestamps between 1970 and the year of the transition use UTC Unix time, and timestamps after the transition use TAI+C Unix time. Note that Unix time isn’t officially defined for dates before 1970.

Any POSIX interface that’s currently returning Unix time (in UTC) should instead start returning legacy Unix time values from the date of the transition onwards.

In this definition, legacy Unix time is essentially the same as Unix time if no new leap seconds were ever inserted anymore. It’s not all that different from what would happen to Unix time if leap seconds were abolished altogether and never replaced. This means that, engineering-wise, this will not lead to any unexpected jumps in timestamps, and most legacy systems would not need to be changed.

There are engineering considerations that will still need to be decided. For example, it’s quite likely that some legacy systems depend on online resources on leap seconds such as https://www.ietf.org/timezones/data/leap-seconds.list, which provides a list of leap seconds. It would be least harmful if popular resources regarding leap seconds such as these were essentially frozen. Legacy systems that depend on resources like these likely expect Unix time and the information from the external resources to match up, so freezing these resources can prevent breakage. This means that transitioning would ideally need to be a coordinated effort.

As it is right now, leap seconds are planned to be abolished from UTC in 2035. The future of UTC after that is still uncertain, however, so some other way of adjusting the time to the rotation of the Earth may still be introduced afterwards. It would be reasonable to do the transition in 2035 so that legacy Unix time and UTC Unix time are perfectly aligned until the first time that UTC is adjusted again. That way, UTC Unix time and legacy Unix time would probably be perfectly aligned for quite a long time. Of course transitioning earlier is also possible. The main reason UTC is getting rid of leap seconds is because of the impact on software systems, and it may not even be necessary to remove leap seconds at all if software engineers themselves would simply move away from timestamping techniques that use leap seconds.

To summarize, the problem with the current definition of Unix time is that it does not have the mathematical properties that engineers expect it to have, which leads to software often breaking whenever a leap second is inserted. I propose to solve this problem once and for all by switching to a definition of Unix time based on TAI instead of UTC, which would lead to arithmetic using Unix time being much less error-prone.

That concludes my proposal. I’ll note that my proposal here is rather informal. I’m not being paid to write this, and as such I have not taken the time to make it entirely proper and formal. If you, however, happen to be someone that does a lot of standards and specifications related work and I have piqued your interest, please feel free to turn this into a formal proposal. I have no clue where or how to submit a formal proposal myself, and honestly I also somewhat prefer to not spend my free time reading IEEE papers.

Feel free to contact me at [redacted], and thank you for reading this all the way to the end.

Footnotes

1. For the exact definition of Unix time, the best resource is no doubt the official specification (where it is called “seconds since the epoch”). The specification defines Unix time using a C expression, which makes it difficult to derive all of the details regarding leap seconds from the definition. I recommend the Wikipedia article for a more clear explanation of leap seconds in Unix time.

Leap seconds are also mentioned in the official rationale, which essentially says that leap seconds are skipped (this is phrased as “leap seconds are ignored”) and justifies this decision by noting that most applications assume that each day is equally long. Notably, the possibility of not having leap seconds altogether (as in TAI Unix time) does not appear to be discussed.