Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can JavaScript handle timestamps beyond 2038?

Tags:

javascript

php

As we know that all dates using Javascript Date constructor are calculated in milliseconds from 01 January, 1970 00:00:00 Universal Time (UTC) with a day containing 86,400,000 milliseconds. This implies that JS uses UNIX timestamp. I set my timer to a date beyond 2038 (say 14 Nov 2039) and run the script:

    <script>
      var d = new Date();
      alert(d.getFullYear()+" "+d.getMonth()+" "+d.getDate());
    </script>

It alerts 2039 10 14 successfully unlike PHP which prints "9 Oct, 1903 07:45:59"

How JS handles this? Explanation is appreciated as I am confused!

like image 779
Parveez Ahmed Avatar asked Nov 14 '13 14:11

Parveez Ahmed


2 Answers

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).

like image 136
deceze Avatar answered Sep 22 '22 20:09

deceze


Javascript doesn't have integer numbers, only floating point numbers (details can be found in the standards document).

That means that you can represent some really large numbers, but at the cost of precision. A simple test is this:

i = 1384440291042
 => 1384440291042
i = 13844402910429
 => 13844402910429
i = 138444029104299
 => 138444029104299
i = 1384440291042999
 => 1384440291042999
i = 13844402910429999
 => 13844402910430000
i = 138444029104299999
 => 138444029104300000
i = 1384440291042999999
 => 1384440291043000000
i = 13844402910429999999
 => 13844402910430000000

As you can see the number is not guaranteed to be kept exact. The outer limits of integer precision in javascript (where you will actually get back the same value you put in) is 9007199254740992. That would be good up until 285428751-11-12T07:36:32+00:00 according to my conversion test :)

The simple answer is that Javascript internally uses a larger data type than the longint (4 bytes, 32bit) that is used for the C style epoc ...

like image 34
Jonas Schubert Erlandsson Avatar answered Sep 22 '22 20:09

Jonas Schubert Erlandsson