Same Date(String) gives different results - javascript

For my WebApp I'm writting unit-tests using Jest and my dev environment is IntelliJ Ultimate 2018.1.
In my unit-tests I need to create Date() from a String. My problem is that when I share this unit-test with my colleague it's not working because the Date(String) is returning a different date (he's using the same dev environment).
For example, In my evironment, when I execute new Date("2018-05-12T19:00:00") I get Sat May 12 2018 19:00:00 GMT+0200 (Romance Summer time)
When my colleague executes exactly the same line of code, he gets Sat May 12 2018 21:00:00 GMT+0200 (Paris, Madrid (heure d'été))
When I add a Z at the end of the date, like new Date("2018-05-12T19:00:00Z") I get Sat May 12 2018 21:00:00 GMT+0200 (Romance Summer time) and he gets the same date with Sat May 12 2018 21:00:00 GMT+0200 (Paris, Madrid (heure d'été))
Why do we get this 2 hours differences when using new Date("2018-05-12T19:00:00") ? We are on the same timezone.
Thanks for your help!

The older ECMAScript 5.1 Spec says in §15.9.1.15:
... The value of an absent time zone offset is "Z".
That means, if you don't specify an offset, it will assume you meant UTC.
Note that since this is the opposite of what ISO-8601 says, this is behavior has been changed in ECMAScript 2015 (6.0), which says in §20.3.1.16:
... If the time zone offset is absent, the date-time is interpreted as a local time.
Thus, it would seem that your colleague is executing the code through an older version of the JavaScript engine. Your string is being interpreted as local time per the newer spec, and theirs is being interpreted as UTC per the older spec. Since you said this is all through Node.js, they should simply upgrade to a newer version of Node.js.
I blogged about this behavior some time ago, if you'd like more details.
If you want to be resilient to older environments, consider parsing the date string yourself or with a library. There are many to choose from. In general, many people do not trust the string parser that comes attached to the Date object because it has changed over the years, has some implementation-specific behaviors, and still does silly things like assuming whole dates like "2018-07-26" should be interpreted as UTC instead of local time like ISO 8601 specifies.

Related

String to date converter issue in js

My local machine in EST timezone.
I'm trying to convert date string to date object in js but getting an day before from date string in date object.
new Date('2020-04-03') for this i'm getting Thu Apr 02 2020 20:00:00 GMT-0400 (Eastern Daylight Time) this output.
new Date('2020/04/03') for this i'm getting Fri Apr 03 2020 00:00:00 GMT-0400 (Eastern Daylight Time) this output.
console.log(new Date('2020-04-03'))
console.log(new Date('2020/04/03'))
I don't know what is the difference between these can anyone explain that?
How i fix this issue?
The reason why the two date parsings give you different results is because it's triggering two different date handling modes.
In one case, 2020-04-03, it's treating the date as an simplified version of ISO 8601 format, for which JavaScript creates a date in the UTC time zone if no time zone is specified.
The second date, 2020/04/03, is not in an officially supported format, so JavaScript falls back to an implementation-specific parsing of the date, so it may not even be consistent across browsers. In that case, it's choosing to use your local time zone.
The MDN article on Date.parse() offers a detailed explanation of how date parsing works in the JavaScript standard and how non-standard behaviors exist among browsers in some cases.
In short, it's a good idea to stick with ISO 8601 dates whenever possible, not only because JavaScript handles them in a consistent way, but they're also easily sorted, and they're widely supported across many programming systems.
Try new Date('2020-04-03 00:00:00')
By default, the date string is parsed in UTC timezone. When you output a date, by default it converts it to your local timezone set by your browser.
To solve, you can enter your date as the UTC equivalent, or simply do as the others have stated here and include the timezone in your date string
let date = new Date('2020-04-03 EST');

How to stringify dates with timezones properly in javascript?

In javascript, I have a date in UTC, and I want to stringify it and parse it but maintain it's UTC. I did this code
var f = { f : new Date("Mon May 27 2019 20:11:13 GMT-0400 (Eastern Daylight Time)")}
undefined
JSON.stringify(f)
"{"f":"2019-05-28T00:11:13.000Z"}"
JSON.parse(JSON.stringify(f))
{f: "2019-05-28T00:11:13.000Z"}
You can see that after I stringified it, it changed to the next day. And then when I parse it, it kept it as a string and even of the next day. I want it so that after I parse it, I get back the Date object of Mon May 27 2019 20:11:13 GMT-0400 (Eastern Daylight Time).
Does anyone know what's wrong?
Thanks
You can see that after I stringified it, it changed to the next day
No, it didn't. "Mon May 27 2019 20:11:13 GMT-0400 (Eastern Daylight Time)" was parsed to a time value of 1559002273000, which defines a moment in time that is that many milliseconds after 1970-01-01T00:00:00Z. It's equivalent to 2019-05-28T00:11:13.000Z (and other timestamps in other time zones). E.g. on a system set to an eastern Australian timezone you'd get "Tue May 28 2019 10:11:13 GMT+1000 (AEST)".
I want it so that after I parse it, I get back the Date object of Mon May 27 2019 20:11:13 GMT-0400 (Eastern Daylight Time)
The date object has no knowledge of the timezone of the original timestamp, it just stores the time value. The string produced by toString just uses the host system timezone setting to generate a "local" timestamp in the format specified by ECMA-262. Note that the timezone name is implementation dependent and since they aren't standardised, the names and abbreviations differ between implementations. E.g. Safari shows "AEST" and Firefox "Australian Eastern Standard Time".
You can use toLocaleString to generate timestamps for different timezones, but the date object doesn't know what the original timezone was and the format may not be what you want.
Also, toLocaleString uses IANA timezone identifiers (e.g. Africa/Kinshasa), which relate to geographic locations that are used to deduce the applicable timezone rather than common names like "Eastern Daylight Time" which are not standardised and can be ambiguous or obscure. The IANA designators mean things like daylight saving and historic timezone offset changes can be applied more easily than with other designators.

Javascript convert timezone issue

I am facing an issue in converting datetime in current timzone.
I am receiving this date string from server in a format "2015-10-09T08:00:00" which is Central Time but when I convert this date time using new Date(strDate) in GMT+5 its returning me below which is incorrect.
var dateObj = '2015-10-09T08:00:00';
new Date(dateObj); // return me below
Fri Oct 09 2015 13:00:00 GMT+0500 (PKT)
Another way I used is to convert by adding timezone offset and its returning me right result but defiantly failed when daylight saving activated.
dateObj2 = '2015-10-09T08:00:00'+'-06:00';
new Date(dateObj2)// return me below
Fri Oct 09 2015 19:00:00 GMT+0500 (PKT)
I appreciated if anyone help OR suggest me efficient way to handle to timezone conversion with daylight saving in JavaScript?
Thank you.
Note that behavior of the code you wrote differs between the browsers:
new Date('2015-10-09T08:00:00').toString()
// "Fri Oct 09 2015 10:00:00 GMT+0200 (Romance Daylight Time)" // Chrome 46 on Windows 8.1
// "Fri Oct 09 2015 08:00:00 GMT+0200 (Romance Daylight Time)" // Firefox 41 on Windows 8.1
// "Fri Oct 09 2015 08:00:00 GMT+0200 (Romance Daylight Time)" // IE11 on Windows 8.1
// "Fri Oct 9 08:00:00 UTC+0200 2015" // IE10 emulation
// "Fri Oct 9 10:00:00 UTC+0200 2015" // IE9 emulation
// on IE8 it even returns NaN!
(my timezone is Paris)
So, Firefox and IE interpret the provided date as specified as if it were in local timezone of the user, whereas Chrome interprets it as UTC, and when printed, it gets converted to user's timezone.
Checking the MDN docs, this is due to differences in EcmaScript 5 and EcmaScript 6 (2015) specifications. It seems that Chrome follows ES5 spec while Firefox and IE11 follow ES6 spec.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse#ECMAScript_5_ISO-8601_format_support (emphasis mine)
The date time string may be in ISO 8601 format. For example,
"2011-10-10" (just date) or "2011-10-10T14:48:00" (date and time) can
be passed and parsed. The UTC time zone is used to interpret arguments
in ISO 8601 format that do not contain time zone information (note
that ECMAScript 2015 specifies that date time strings without a time
zone are to be treated as local, not UTC).
Unfortunately Date object in JavaScript is famous for its quirks and cross-browser inconsistencies, particularly on ambiguous input.
I wrote here
how you can leverage moment.js or native Intl API to make sure your date will not be converted to user's timezone (the secret is to use UTC manipulating methods).
In general it's best to always specify either both time and UTC offset, or just a UTC timestamp, to make sure your input is unambiguous.
Coming back to your example, you can use following code:
moment('2015-10-09T08:00:00-06:00')
.utcOffset(+300).locale('en_gb').format("LLLL")
// "Friday, 9 October 2015 19:00" cross-browser
in which you say "this is date in UTC-0600, please convert and print it as UTC+0500 (+300 minutes)". Then you can pass in which locale you want it printed (i.e. language + culture specific settings, e.g. en_gb uses 24 hour clock while en_us 12-hour clock) and use multitude of date formats supported by moment.js.

Chrome on Mac displays time with (MST), yet Chrome on PC displays time with (Mountain Standard Time)

I'm using the jQuery Weekly Calendar plugin (https://github.com/robmonie/jquery-week-calendar/wiki/). When I alert the startTime and endTime (which also go in a database), I get different results on Mac and Windows.
Chrome on Mac shows the time as:
Sat Nov 26 2011 13:10:00 GMT-0700 (MST)
Where as Chrome on Windows shows the time as:
Sat Nov 26 2011 13:10:00 GMT-0700 (Mountain Standard Time)
Any ideas why that would be happening? In the jQuery Weekly Calendar script, I was thinking maybe these lines need to be changed somehow:
$timestampsOfOptions.start[timeslotTimes[i].startFormatted] = startTime.getTime();
$timestampsOfOptions.end[timeslotTimes[i].endFormatted] = endTime.getTime();
But I'm not really sure to be honest.
getTime() isn't what needs to be changed -- it returns a numeric value.
The output you're looking at looks like the raw output from JavaScript's native Date.toString() method, whose output is not guaranteed to be in any specific format. In particular, the names of time zones are often not the same from system to system -- if you need consistent output, you're probably out of luck.

Javascript Date.parse bug when dash-delimited and starts with year

Am seeking confirmation if this is a bona fide documentation and/or implementation bug with Javascript's Date.parse method.
The docs I'm referring to are at https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/parse and they say 'If you do not specify a time zone, the local time zone is assumed.'
But the following code shows that, despite not specifying a time zone, local time is not being assumed (but rather my timezone offset is being applied), if the string passed to Date.parse begins with the 4-digit year representation, and is dash-delimited.
var euroStyleDate = '2011-10-04';
var amerStyleDate = '10/04/2011';
var euroStyleParsed = Date.parse(euroStyleDate);
var amerStyleParsed = Date.parse(amerStyleDate);
console.log(euroStyleParsed); //1317686400000
console.log(amerStyleParsed); //1317700800000
console.log(new Date(euroStyleParsed));
//Date {Mon Oct 03 2011 20:00:00 GMT-0400 (Eastern Daylight Time)}
console.log(new Date(amerStyleParsed));
//Date {Tue Oct 04 2011 00:00:00 GMT-0400 (Eastern Daylight Time)}
There may even be other cases, and I'm sure I'm not the first to discover this if I am incorrect. So beyond confirmation, I'd surely love to be pointed at more in-depth information on this if anybody knows of pertinent links.
I'm experiencing this in FF3, Chrome for Windows and of course just to be special IE8 doesn't even seem to able to perform the conversion on 2011-10-04 whatsoever: I'm just getting an empty string in my application
Thanks in advance for any further insight or resources.
I ran into this concept, too. For anyone googling "Javascript dates dashes slashes" like I was, this is the clearest demonstration that I can think of as to what's going on here.
In short, slashes means local time zone, and dashes means UTC. Other answers has explanations regarding why.
<script type="text/javascript">
var
testB = new Date("2012/02/09"),
testC = new Date("2012-02-09");
alert(testB.toString());
alert(testC.toString());
alert(testC.toUTCString());
</script>
**Update:**It looks like there are several different standards at work here:
The EMCAScript < 5 standard allowed for dates in the standard IETF format, e.g. Sun Oct 03 2010. With these dates, the local timezone is assumed.
In ECMAScript 5, a limited version of the ISO 8601 standard is also allowed, e.g. 2010-10-03. The spec seems to say (perhaps following ISO 8601?) that in this case, the UTC timezone is assumed if one is not specified.
I haven't found a spec that says Date.parse can handle mm/dd/yyyy dates, but my browser (Chrome 14) clearly can, and probably other browsers can too. This appears to follow standard 1 above, assuming the local timezone. Given that it's not in the spec, however, I would recommend not using this version, as it's likely to be browser-dependent (and I have no idea whether 10-03-2010 would result in a different date if I had a European locale set on my browser).
There are a few issues with the native Date.parse function in most interpreters - I have often had timezone issues like the one you describe. So in general, I either use a library like Datejs or I write my own parsing functions. The DateTime module of the SIMILE AJAX library has a pretty good example function for parsing ISO-8601 dates (what you're referring to as euroStyleDate, plus an optional time component).
When setting dates, I generally use new Date() and then use the setUTC*() functions to set the different date elements to my desired precision. It's not perfect, but at least you're dealing with a clear timezone.

Categories

Resources