Search code examples
javascriptdatetimezoneunix-timestamp

Weird Javascript Timezones with Date()


Javascript hopeless here but I've got a problem I can't seem to understand, and don't know whether it's defined behavior in JS or not...

From what I can understand, new Date() returns the current time in the current timezone as reported by the browser. At the current time of writing this, I am in Milan, Italy (GMT +0200 CEST), so when performing the below:

var date = new Date();
console.log(date);
console.log(date.getTimezoneOffset());

I get, as expected:

Sun Oct 07 2018 15:42:12 GMT+0200 (Central European Summer Time)
-120

However, again from what I understand, throwing milliseconds into the Date Constructor creates a date based off of Epoch Time, 1st January 1970 00:00:00 GMT +0000 - So why if I perform:

var date = new Date(0); // Note The 0
console.log(date);
console.log(date.getTimezoneOffset())

Do I get:

Thu Jan 01 1970 01:00:00 GMT+0100 (Central European Standard Time)
-60

Did the browser for some reason change the timezone it thinks I am in? This is causing quite a few problems for me retrieving a unix timestamp from a database, and displaying it in the user's current timezone!

Any help or advice on this would be much appreciated!

Many thanks! :)


Solution

  • The numeric timestamp value inside every Date instance, no matter how it is constructed, represents an offset from a fixed UTC "epoch" time. When you construct a date in your locale, the timezone offset is taken into account when the Date instance timstamp is set. The timezone offset is also taken into account when you access parts of the date via locale-relative APIs like .getTimezoneOffset().

    Thus what matters is how you get date/time information out of the Date instance. If you use UTC APIs, you get UTC time information. If you use locale-relative APIs, you get locale-relative values.

    let d = new Date();
    console.log("locale-relative: " + d);
    console.log("UTC: " + d.toUTCString());

    Now, as to how you handle the system timestamp values you've got in your database, that depends on how your application works and what the dates mean in that context. If it's important that users see the dates in terms of what your server(s) will do with them, format the dates on the server with locale-relative APIs. That would make sense if your application does some work based on local time. For example some banking applications (in the US) do things at night, but "night" in terms of late evening hours in the continental US.

    If, on the other hand, the dates you store should be shown to your users in terms of their locales, then send the client the timestamp and format your dates as strings at the client with locale-relative APIs. That would be appropriate for an application that allows users to set up alarms etc: generally it makes sense for the user to think in terms of their own local time.