Why Do Timestamps Have a Limit to 2038

Why do timestamps have a limit to 2038?

The limit is imposed by the 4 byte signed integers that most C libraries use for representing that count. Quick math (assumes 365 day years, not exactly correct):

2147483648 seconds ~ 68.1 years

This also implies a lower limit of ~1900. Some libraries have started to introduce 64 bit epoch counts, but they are few and far between for the moment.

Why can JavaScript handle timestamps beyond 2038?

32bit PHP uses 32bit integers, whose max value puts the last UNIX timestamp that can be expressed by them in 2038. That's widely known as the Y2K38 problem and affects virtually all 32bit software using UNIX timestamps. Moving to 64bits or libraries which work with other timestamp representations (in the case of PHP the DateTime class) solves this problem.

Javascript doesn't have integers but only floats, which don't have an inherent maximum value (but in return have less precision).

PHP & mySQL: Year 2038 Bug: What is it? How to solve it?

I have marked this as a community wiki so feel free to edit at your leisure.

What exactly is the Year 2038 problem?

"The year 2038 problem (also known as Unix Millennium Bug, Y2K38 by analogy to the Y2K problem) may cause some computer software to fail before or in the year 2038. The problem affects all software and systems that store system time as a signed 32-bit integer, and interpret this number as the number of seconds since 00:00:00 UTC on January 1, 1970."



Why does it occur and what happens when it occurs?

Times beyond 03:14:07 UTC on Tuesday, 19 January 2038 will 'wrap around' and be stored internally as a negative number, which these systems will interpret as a time in December 13, 1901 rather than in 2038. This is due to the fact that the number of seconds since the UNIX epoch (January 1 1970 00:00:00 GMT) will have exceeded a computer's maximum value for a 32-bit signed integer.



How do we solve it?

  • Use long data types (64 bits is sufficient)
  • For MySQL (or MariaDB), if you don't need the time information consider using the DATE column type. If you need higher accuracy, use DATETIME rather than TIMESTAMP. Beware that DATETIME columns do not store information about the timezone, so your application will have to know which timezone was used.
  • Other Possible solutions described on Wikipedia
  • Upgrade your Mysql to 8.0.28 or higher


Are there any possible alternatives to using it, which do not pose a similar problem?

Try wherever possible to use large types for storing dates in databases: 64-bits is sufficient - a long long type in GNU C and POSIX/SuS, or sprintf('%u'...) in PHP or the BCmath extension.



What are some potentially breaking use cases even though we're not yet in 2038?

So a MySQL DATETIME has a range of 1000-9999, but TIMESTAMP only has a range of 1970-2038. If your system stores birthdates, future forward dates (e.g. 30 year mortgages), or similar, you're already going to run into this bug. Again, don't use TIMESTAMP if this is going to be a problem.



What can we do to the existing applications that use TIMESTAMP, to avoid the so-called problem, when it really occurs?

Few PHP applications will still be around in 2038, though it's hard to foresee as the web hardly a legacy platform yet.

Here is a process for altering a database table column to convert TIMESTAMP to DATETIME. It starts with creating a temporary column:

# rename the old TIMESTAMP field
ALTER TABLE `myTable` CHANGE `myTimestamp` `temp_myTimestamp` int(11) NOT NULL;

# create a new DATETIME column of the same name as your old column
ALTER TABLE `myTable` ADD `myTimestamp` DATETIME NOT NULL;

# update all rows by populating your new DATETIME field
UPDATE `myTable` SET `myTimestamp` = FROM_UNIXTIME(temp_myTimestamp);

# remove the temporary column
ALTER TABLE `myTable` DROP `temp_myTimestamp`

Resources

  • Year 2038 Problem (Wikipedia)
  • The Internet Will End in 30 Years

JSON Web Token and the year 2038 bug

JSON doesn't put a limit on the precision of numbers, therefore the JWT format itself has no overflow issues. It all depends on the implementation.

Some implementations, such as JavaScript, treat all JSON numbers as double precision floating point numbers. While they're not going to overflow until after the heat death of the universe, they will start to become inaccurate in a little under 300 million years, and the problem will get worse as time goes on (problems such as you create a token that expires in one hour, but that value can't be expressed as a double precision float, the nearest value is in 2 hours, so it doesn't expire until 2 hours time).

Other implementations might use 64 bit signed integers. These will overflow in 300 billion years, well after the sun becomes a red giant and consumes the earth.

The only implementations that are vulnerable to the Y2038 problem are implementations that decide to use 32 bit signed integers when parsing the date. Such an implementation would be stupid. It doesn't matter what format you choose, you can't protect against stupidity - and ISO8601 does nothing to help here, because while that may be what appears on the wire, every single implementation is going to parse it into some number of time units since some epoch, since that's the way all computers work with dates and is the only way to practically do calculations such as is the token expired yet. Hence, every implementation, even when using ISO8601, is susceptible to choosing a number representation with to low a precision to handle dates after a particular time, including choosing signed 32 bit integers to represent the date as seconds since 1970, a la the Y2038 problem. It's up to each implementation to choose an appropriately sized number type to represent their parsed dates, which you'll probably find they all do (and if not, you should report a bug).

So, no, there is nothing wrong with JWTs using seconds since the UNIX epoch for dates.

What exactly is considered to be a Timestamp? Does it have standard formats?

A timestamp is basically a numeric value of seconds, between 1st January 1970, to January 19, 2038 (aprox.). That is simply because the integer is "maxed out" at 2147483648 seconds.
You can read more about it here.

As for the format, a lot of languages ( I assume all, but am not sure) allow you to set your own format, like dd/mm/yyyy, mm/dd/yyyy etc.

Here's an example in PHP. This gets the current date, and outputs it in your desired format.

$date=date("Y/m/d");
echo $date;

The output will be 2019/11/20

Not every language is the same tho, so this may vary from language to language.
Hope it helps!

This is also worth checking out!

Accessing dates in PHP beyond 2038

You can alternatively use the DateTime class, which internally represents the time components independently. Thus it is not susceptible to the 2038 limitation (unless you use ::getTimestamp).

year 2038 issue - 64 bit (Linux OS, php, mysql)

Simply put, for MySQL, store dates as DATETIME rather than TIMESTAMP.

TIMESTAMP is 4 bytes, so there is no physical room to store more seconds than since 1970-1-1 to 2038-01-19...

DATETIME, instead, has a range of 1000-1-1 to 9999-12-31...

See also this complete question/answer: PHP & mySQL: Year 2038 Bug: What is it? How to solve it?

UPDATE:
One possible alternative I see, if you CAN'T change your fields types, is to interpet your timestamps differently...

I mean: if the first event your application will keep track of is - say - 2000-1-1, you could implement a filter on backend (or in a stored procedure inside the database), to add (2000-1-1 - 1970-1-1) seconds to your timestamps when reading, and subtract the same amount when reading... This should give you 30 more years of 'survival'...



Related Topics



Leave a reply



Submit