0

I am facing a weird situation where subsequent calls to the Date constructor passing a timestamp are returning date objects with different timezones.

different timezones subsequent calls same browser

This is causing a problem when I use the object to get the day of the month.

new Date(1509228000000).getDate()
29
new Date(1509314400000).getDate()
29

If it was using the same timezone the results would be 29 and 30.

My understanding is that javascript should use the system or browser timezone. I don't understand how two calls, one right after the other, return objects with different timezones.

I am using Chrome Version 61.0.3163.100 (Official Build) (64-bit).

clarifying

I understand a timestamp(a number of milliseconds) can be represented in different timezones. What I don't understand is how calling the Date constructor with different values result in Date objects with different timezones in the same machine and browser.

  • 1
    CET and CEST are just short names for respectively "Central European Time" and "Central European Sumer Time". It's still the same timezone, the only difference is if Daylight Saving Time is in effect or not. –  Oct 09 '17 at 14:19
  • And the day's value depends on the timezone you convert the dates to: `1509228000000` can be [29 in Europe](https://www.epochconverter.com/timezones?q=1509228000000&tz=Europe%2FBerlin) or [28 in America](https://www.epochconverter.com/timezones?q=1509228000&tz=America%2FNew_York), while `1509314400000` can be [29 in America](https://www.epochconverter.com/timezones?q=1509314400000&tz=America%2FNew_York) and [30 in Australia](https://www.epochconverter.com/timezones?q=1509314400&tz=Australia%2FSydney). So *"the results should be"* will depend on what timezone you're working with. –  Oct 09 '17 at 14:29
  • thanks Hugo, yes, that's true. But my point is that I don't really care which timezone is being used as long as it is used consistently. I get the timestamp from the server and use it to create a date object which should be created with the local timezone. What confuses me is that one timestamp is converted to one timezone and another timestamp in convert to a different timezone in the same machine and browser. Why is this happening ? – Felipe Taiarol Oct 09 '17 at 14:44
  • 1
    In the European Union CET is only valid from October to March and it's then replaced by CEST. That's as coherent as it can get, unless you opt to ignore Governments and switch your computer to UTC ;-) – Álvaro González Oct 09 '17 at 14:56
  • As I said, both CET and CEST are the same timezone. "CEST" just indicates that the timezone is in Daylight Saving Time, but it's still the same zone (and the browser didn't change anything). And if you want to get a specific date, you must care about timezones, because the same timestamp can represent a different date in each timezone, as I explained above in the previous comments –  Oct 09 '17 at 15:43
  • Not direclty related, but for the sake of correctness, CET and CEST aren't real timezones. They're just [ambiguous and not standard](https://stackoverflow.com/a/18407231/7605325) abbreviations that are used by [more than one timezone](https://www.timeanddate.com/time/zones/cet). But anyway, the browser is not changing anything, it's only DST effects acting –  Oct 09 '17 at 15:44

2 Answers2

2

In EU countries, Central European Summer Time (CEST) transitions to Central European Time (CET) this year on October 29, 2017 at 3:00 AM local time. Your results simply reflect that change. The behavior is expected. Reference here.

To be clear, both the values you showed are on October 29th in the local time zone. The correct result from the getDate() call is indeed 29.

For further understanding, I suggest you read:

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • Ok, I understand it now. It was a tricky one because of the summer time. The timezone the browser uses to create the date object from the timestamp changes based on the timestamp. If the timestamp is during my location day light saving time it uses CEST, otherwise it uses CET. That was the tricky part. I thought the choice of timezone would depend only on the machine and maybe browser but it actually also depends on the timestamp itself because my location timezone changes during day light saving time. – Felipe Taiarol Oct 11 '17 at 07:48
  • @FelipeTaiarol Not just summer time, actually. Some times governments just decide to change the country's time zones. For instance, Spain increased the offset of its two time zones during Second World War and it remained that way until today. – Álvaro González Oct 11 '17 at 09:20
  • As others have stated, the time zone is not used when you create a `Date` object from a numeric timestamp. It is used when you emit that object as a string, and in certain function calls like `getDate`. Also, the time zone itself is not changing. Only the time zone *offset* and it's associated abbreviation are changing. The rules for how it changes are part of the time zone definition. – Matt Johnson-Pint Oct 11 '17 at 14:36
2

If you let me relax the overall technical accuracy (while hopefully not saying anything blatantly wrong), I think JavaScript Date object is better understood if you think of it as a variable that stores an absolute specific point in time (a Unix timestamp if you like). This internal value does not have time zone information attached because it isn't essential (it's an absolute value after all) and it's everything that JavaScript needs... until it has to interact with the outside world, i.e., parse or generate a human-readable date.

Such dates are always local, thus need a time zone. And the approach used by JavaScript creators is to use two time zones:

  • UTC
  • Whatever time zone is configured as default in the computer where JavaScript code runs at

And the funny thing is that which one gets chosen depends on the method involved. If you call .getFullYear() you get local time, if you call .getUTCFullYear() you get UTC. Not too bad, is it? Well, you also have .toDateString(), .toGMTString(), .toISOString()... Could you tell which time zone each uses without looking at docs? Or even after looking at docs? And, hey, date constructor can actually use both, depending on the string and browser!

Said that, it's easier to understand that your two code samples point to very specific moments in time. Magic happens when you call .getDate(), which is expected to use local time. Your computer is apparently located somewhere in Europe. As per most local legislations, there's daylight saving time in effect during several months and the way it's technically implemented is by actually switching between two related by different time zones: CET (Central Europe Time) and CEST (Central Europe Summer Time). JavaScript engine is smart enough to realise that local time zone changes and is able to pick the correct one for the absolute moment in time stored in the object.

If you're curious, this is possible because the browser has a database with up-to-date time zone transitions. Such database is a valuable resource shared by many programs.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
  • Thanks Álvaro, I understand what you are saying. The timestamp is the number of milliseconds that happened since 01-01-1970 00:00:00 in UTC timezone. That number can be represented in different timezones, CET, CEST, etc. Like you said, the timezone used to create the date object is: "Whatever time zone is configured as default in the computer where JavaScript code runs at" What I still don't understand is how two calls two the Date constructor with a timestamp in the same machine and in the same browser one right after the other return date objects with different timezones. – Felipe Taiarol Oct 10 '17 at 07:58
  • Your explanation makes sense if the calls were in different machines, it makes sense if the calls were in the same machine and some time apart from each other (one during summer time and the other during winter time, for example), maybe I am missing something here but it doesn't make sense to me when they happen one right after the other. – Felipe Taiarol Oct 10 '17 at 08:02
  • 1
    No, there's no time zone used to create the object. You say `1509228000000` and that's a specific point in time—time zone is not involved at all. It's like saying "create a variable that points to the moment when Apollo 11 landed on the Moon". What time zone? It's irrelevant. You don't need it at all, until you make questions like "What time was it in Sidney? How about Berlin?". – Álvaro González Oct 10 '17 at 08:41
  • 1
    @FelipeTaiarol Just for the sake of correctness (and my habit of being pedantic), your timezone doesn't change. What changes is the **offset** (the difference from UTC - read more about the difference [here](https://stackoverflow.com/tags/timezone/info)). The same timezone can use either CET or CEST, those are just "nicknames" used by each offset (CEST is used during DST). But the browser is not changing the timezone: it's just checking if, at the instant represented by the timestamp, the zone was in DST or not, and choose the respective "nickname". But the timezone is always the same. –  Oct 10 '17 at 12:43
  • @FelipeTaiarol You can check what's the timezone using `Intl.DateTimeFormat().resolvedOptions().timeZone` - this is not supported by all browsers, so if it doesn't work, you can use [momentjs](https://momentjs.com) and [moment timezone](https://momentjs.com/timezone) libs, and call `moment.tz.guess()`. With this you'll get the correct timezone name (not the ambiguous and non-standard names like CET and CEST), so you can see that the zone doesn't change. –  Oct 10 '17 at 13:02