-1

Please see the code example below from Google Chrome:

new Date('Thu Jul 27 2017 13:10:42 GMT-0500')
Result: Thu Jul 27 2017 19:10:42 GMT+0100 (BST)

new Date('Thu Jul 27 2017 13:10:42 GMT+0500')
Result: Thu Jul 27 2017 09:10:42 GMT+0100 (BST)

I would read the first date current time as being 13:10 which is -0500 hours off from GMT but the result it gives is +5 hours in the future +1 hour BST. In a similar vein the second date works the opposite way being +0500 hours off but returning -5 hours in the past +1 BST.

Firefox works in a similar way but it seems without the BST:

new Date('Thu Jul 27 2017 13:10:42 GMT-0500');
Date 2017-07-27T18:10:42.000Z

new Date('Thu Jul 27 2017 13:10:42 GMT+0500')
Date 2017-07-27T08:10:42.000Z

IE Edge gives me these results:

new Date('Thu Jul 27 2017 13:10:42 GMT-0500')
Thu Jul 27 2017 19:10:42 GMT+0100 (GMT Summer Time)

new Date('Thu Jul 27 2017 13:10:42 GMT+0500')
Thu Jul 27 2017 09:10:42 GMT+0100 (GMT Summer Time)

Can anyone help throw some light on this please?

EDIT - this is not a duplicate of 'Why does Date.parse give incorrect results?' because I am not using the parse() method explicitly.

Please note: I am trying to create a date object that is not in the same timezone as my browser.

If this is not possible I might have to solve my current problem with some basic math (current time +/- the timezone required) - shame if I cannot do this with a native JS Date object.

user1360809
  • 725
  • 2
  • 13
  • 24
  • Everything is fine... When it is 13 in Paris, it is 6 in Montreal... So 6 in Montreal is still 13 in Paris. – Salketer Jul 27 '17 at 13:37
  • 1
    Actually, you are using "in the past" and "in the future" makes me wonder if you are well aware of what timezones are. – Salketer Jul 27 '17 at 13:40
  • @Salketer apologies regarding my use of 'in the past' and 'in the future'. Regarding the behavior I was expecting to create a new date object which has a value equal to that passed in as a string...and that wasn't the result I got – user1360809 Jul 27 '17 at 13:43
  • 1
    You are getting the correct dates. But the output is being converted to localtimes in whatever default timezone each browser uses. 13:10 in `-05:00` offset **is** the same as 18:10 in UTC (`Z`) and 19:10 in BST (British Summer Time). Those values (13:10, 19:10, etc) are just representations of the date, but its **value** is correct (all represent the same instant). You could call `toUTCString()` or `getTime()` to check that the values are the same. –  Jul 27 '17 at 13:55
  • @Hugo OK, I think I see where I am going wrong. Isn't it possible to make a date object that isn't converted to local times? – user1360809 Jul 27 '17 at 14:02
  • 1
    Actually, a Date ifself has no format, it just represents the number of milliseconds since `1970-01-01T00:00Z`. When **printing** the date object, this milliseconds value is "translated" to some meaningful human-readable value (AKA, a localtime in some timezone - and the browser uses some default zone configured somewhere). But the date object itself is not in a specific timezone. An alternative to have an output "independent" of timezone would be to call `toUTCString()`. –  Jul 27 '17 at 14:12
  • Or maybe you need an external library: https://momentjs.com/docs/#/parsing/parse-zone/ –  Jul 27 '17 at 14:18
  • `Date.parse(string)` and `new Date(string)` must, per ECMA-262, parse the string in exactly the same (implementation dependent) way. Saying "*I'm not using Date.parse*" doesn't change that. Date objects don't have a time zone, they are UTC. How a particular parser parses a non-standard string is entirely up to the implementation (see the duplicate). – RobG Jul 28 '17 at 01:59

2 Answers2

0

The default conversion of a Date instance to a string gives you the date and time in terms of the local timezone. If you're doing it in the browser console, you can't even rely on that, because the console itself is free to do whatever it wants. Firefox's console seems to extract the UTC representation; if you call

new Date('Thu Jul 27 2017 13:10:42 GMT-0500').toString()

instead you get the local time.

Dates are based on the idea of UTC timestamps and the notion that local time is generally important. Creating a date from a string gives you a timestamp meaningful (well, as meaningful as possible) for the string, but subsequently the Date instance is by default treated as something relevant to the local context. You can always use the UTC APIs to extract the UTC time if you want.

Pointy
  • 405,095
  • 59
  • 585
  • 614
0

This question seems to stem from unfamiliarity either with how date strings are parsed by the built–in parser or with how they are formatted by various built–in toString methods.

The same parser is used by Date.parse and the Date constructor, it doesn't matter which is used in terms of how the string is parsed to a time value. The only difference between the two is that Date.parse returns the time value as a number, whereas the Date constructor uses the time value to create a Date instance (which is the only value that a Date instance holds).

The time value itself is milliseconds since 1970-01-01T00:00:00Z, so has no time zone (and means Date instances are effectively UTC). The value returned by getTimezoneOffset and the timezone displayed in toString methods (if there is one) is from the host system, it's not a property of Date instances or the Date constructor.

The timestamp pairs in your question represent exactly the same moment in time, but in different time zones.

Thu Jul 27 2017 13:10:42 GMT-0500 is Thu Jul 27 2017 18:10:42 GMT.
Thu Jul 27 2017 19:10:42 GMT+0100 (BST) is also Thu Jul 27 2017 18:10:42 GMT.

The value returned by Date.prototype.toString is entirely implementation dependent. When you send a date to output, the host may use any method it likes to represent the Date and may format it any way it wants. In the above, it seems the host timezone (UTC+0100) has been used with the default toString, which may return a differently formatted string in different implementations.

However, recent browsers seem to have settled on RFC 2822 format. Other methods that typically return different formats are toISOString and toLocaleString (noting that all three methods could return an ISO 8601 format string and be consistent with the ECMA-262, though I don't know of any implementations that do).

The next two dates also represent exactly the same moment in time:

Thu Jul 27 2017 13:10:42 GMT+0500 is Thu Jul 27 2017 08:10:42 GMT
Thu Jul 27 2017 09:10:42 GMT+0100 (BST) is also  Thu Jul 27 2017 08:10:42 GMT

Again, the host timezone has been used to generate the output string.

As for "Firefox works in a similar way but it seems without the BST", see above. ECMA-262 only requires the the format be convenient and human readable. In this case, the browser developers have chosen to use an ISO 8601 format with no offset (i.e. UTC+0000).

So:

Thu Jul 27 2017 13:10:42 GMT-0500 is Thu Jul 27 2017 18:10:42 GMT+0000
2017-07-27T18:10:42.000Z is also Thu Jul 27 2017 18:10:42 GMT+0000

The choice not to use a timezone offset is entirely up to the browser developers and is consistent with ECMA-262.

If your issue is with how date strings are parsed, the duplicate is Why does Date.parse give incorrect results?. If it's with how dates are formatted, the duplicate is Where can I find documentation on formatting a date in JavaScript? The answers to those two questions should answer any issue raised in the OP.

RobG
  • 142,382
  • 31
  • 172
  • 209