0

Does anybody know why following happens with the timestamp integers using JavaScript Date? If I use integer -2500938981 to transpose to YYYY-MM-DD hh:mm:ss, I get 1890-09-30 22:43:59. Then for -2500938980 I would expect a timestamp 1890-09-30 22:44:00. But actually what I get is 1890-09-30 22:43:40

var datetime1 = new Date((-2500938981) * 1000)
var datetime2 = new Date((-2500938980) * 1000)
// dt1 in YYYY-MM-DD hh:mm:ss is 1890-9-30 22:43:59
var dt1 = datetime1.getFullYear() + "-" + (datetime1.getUTCMonth() + 1) + "-" + datetime1.getUTCDate() +
  " " + datetime1.getUTCHours() + ":" + datetime1.getUTCMinutes() + ":" + datetime1.getSeconds();
// dt1 in YYYY-MM-DD hh:mm:ss is 1890-9-30 22:43:40
var dt2 = datetime2.getFullYear() + "-" + (datetime2.getUTCMonth() + 1) + "-" + datetime2.getUTCDate() +
  " " + datetime2.getUTCHours() + ":" + datetime2.getUTCMinutes() + ":" + datetime2.getSeconds();
  
console.log(dt1)
console.log(dt2)

Also tested here: https://www.w3schools.com/code/tryit.asp?filename=GK1UBRVKDS91

In addition, also tested on https://www.freeformatter.com/epoch-timestamp-to-date-converter.html, following happens:

-2500938981 -> 9/30/1890, 11:59:59 PM
-2500938980 -> 9/30/1890, 11:43:40 PM

On https://www.epochconverter.com/ it works OK:

-2500938981 -> GMT: Tuesday, September 30, 1890 10:43:39 PM
-2500938980 -> GMT: Tuesday, September 30, 1890 10:43:40 PM
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • No, you're not. You're using integers `-2500938981000` and `-2500938980000`, because you're multiplying your numbers by 1000 in the `Date` constructors. So step 1 is to make sure you understand your code, so you can investigate the _real_ problem. – Mike 'Pomax' Kamermans Oct 24 '20 at 15:56
  • I made you a snippet – mplungjan Oct 24 '20 at 15:57
  • Times and timezones weren't fully standardized yet in 1890 so you'll see all kinds of strangeness, depending on what your timezone is. On my computer it shows 22:43:28 and 22:43:29 and the timezone is GMT+0139. – Guy Incognito Oct 24 '20 at 16:01
  • I think you misread 39 as 59. I get "For integer -2500938981 is timestamp 1890-09-30 22:43:*39*". [Wolfram Alpha agrees](https://www.wolframalpha.com/input/?i=2500938981++seconds+before+January+1%2C+1970+UTC). – Raymond Chen Oct 24 '20 at 16:18
  • @GuyIncognito—there's no standard defining timezones, the concept of "timezone" is fluid (compare [this](https://spin.atomicobject.com/2016/07/06/time-zones-offsets/) [this](https://en.wikipedia.org/wiki/List_of_UTC_time_offsets) and [this](https://www.thoughtco.com/offset-time-zones-1434512)). The problem here is the offset, which is determined by regional or national administrations and changes from time–to–time. It's usually set to some convenient value so that solar noon roughly aligns, on average over the year, to local noon by perhaps ±1 hour or so. Then there is daylight saving… – RobG Oct 24 '20 at 21:46
  • Look at the offset for `new Date(1883,8,3).toLocaleString('en',{timeZone:'America/New_York',timeZoneName:'short'})`. – RobG Oct 25 '20 at 04:12
  • @RobG As the OP knows only too well, the moment in time that they have picked was indeed one of those times when clocks changed. In this case, this happened in Budapest when, at 1890-10-01 00:00:00, it switched to Central European time. The change was 1 hour, 16 mins and 20 secs - putting it back to 22:43:40. Prior to that change, the previous second would have been 23:59:59. On a Windows machine, there is a file called **timezones.xml** that stores all of the date/time changes from the late 1800's. – ATD Oct 25 '20 at 05:24
  • JavaScript store numbers as floating point, and you may hit precision problem (not enough bits in matissa to store such long integer). In any case: never use millisecond with timestamps (false precision: timestamps are already off 18000 ms, and just from 1970). – Giacomo Catenazzi Oct 26 '20 at 06:07
  • Thanks for all explanations and adding the snippet. And yes, @Mike'Pomax'Kamermans you are right, I stated wrongly which integers I use. They are of course not seconds but actually milliseconds for the javascript code. – user3761039 Oct 27 '20 at 18:30
  • @RaymondChen for me also Wolfram Alpha works correctly. But snippet and w3schools.com both output 1890-9-30 22:43:59 and 1890-9-30 22:43:40 for me. – user3761039 Oct 27 '20 at 18:30
  • The lesson being "don't use the built-in Date object for anything even remotely arithmetical, like a some date-relative-to-now, use a real datetime library like [moment.js](https://momentjs.com/) and always specify which timezone you're working in because the rule can be _wildly_ different depending on which one you need to work in". – Mike 'Pomax' Kamermans Oct 27 '20 at 18:52
  • I get the correct answer on snippet and w3schools. Mind you, they run the code in your browser, so the real issue is that your browser's Date math is broken. – Raymond Chen Oct 27 '20 at 19:51

0 Answers0