Issue with Date.parse in Chrome - javascript

The implementation of Date.parse in Chrome has very unexpected behavior.
For example, Date.parse('foo 2014') should ideally return NaN as it is not a proper date format. But in Chrome this returns the value 1388514600000, which is equivalent to the date "Wed Jan 01 2014 00:00:00 GMT+0530 (India Standard Time)".
As long as the string ends with some sort of year, a proper date value is returned. This will not let us to properly validate dates.
According to ECMAScript this behavior is implementation dependent and chrome does a very loose validation and some how converts to a date.
Is there anyway in chrome to properly validate date without using any library or using heavy logic and matching patterns?

You can test date string with regular expression before parse.

Related

new Date() works in Chrome but throws 'Invalid date' in Firefox

Used ng prime datepicker in application.
Getting date in Fri May 14 2021 00:00:00 GMT+0530 (India Standard Time) format as response from api.
Then converting Fri May 14 2021 00:00:00 GMT+0530 (India Standard Time) this response with new Date().
Then binding the response to ng prime datepiker.
Working fine in chrome.
In firefox it is showing "Invalid date".
See the documentation for the Date constructor:
A string value representing a date, specified in a format recognized by the Date.parse() method. (These formats are IETF-compliant RFC 2822 timestamps, and also strings in a version of ISO8601.)
Since you aren't passing one of those formats, you are dependent on implementations having non-standard support for your format.
Chrome does. Firefox doesn't.
Use a date parsing library that lets you specify the format (such as date-fns/parse) or change the API so it outputs dates in the standard format.
You can as well, use the dateStringToDate function in date-fran module. It converts date formats of the form "Fri May 14 2021" to actual date instances.

Chrome 58.0.3029.110 version not converting date in correct local timezone

Chrome not giving a correct result on date conversion:
Date : "2017-05-22T14:00:00"
On doing this in chrome console:
new Date("2017-05-22T14:00:00");
Output is:
Mon May 22 2017 14:00:00 GMT+0530 (IST)
This is wrong because I am in IST. It should have rather given output as
Mon May 22 2017 19:30:00 GMT+0530 (IST)
Safari is giving correct results. Chrome was right before but I think latest update is having an issue.
Found that appending Z in date string results correct date value.
new Date("2017-05-22T14:00:00Z");
The input value is being interpreted correctly. ECMAScript 2015 (ES6) section 20.3.1.16 states:
If the time zone offset is absent, the date-time is interpreted as a local time.
This aligns with the ISO-8601 standard as well.
In previous versions of ECMAScript, UTC was assumed when no offset was provided. That goes against ISO-8601, and was implemented inconsistently across various environments.
If you want the input to be interpreted as UTC, then you should provide an offset, either +00:00, or Z as part of the input string.
However, if you are talking about how a Date object should be displayed when logged to the debug console, that is not defined in the spec. In some environments, you will see the output of date.toString(), which shows the local date and time in a non-standard format, and in other environments (such as FireFox) you will see the output of date.toISOString(), which shows the UTC date and time in ISO-8601 format.
There's no spec about which to show, so either would be valid. If you want to see specific output, don't just log a Date object, call a function on the object that returns a string and log that instead.

JavaScript date-only format guaranteed to be interpreted as local time in modern browsers

I am looking for a date format (only year, month and day, no time component), that will be guaranteed to be interpreted as local time, in all reasonably modern browsers, when passed to the Date() constructor in JavaScript.
The (3-letter English month abbreviation) (2-digit date) (4-digit year) format seems to work. When I do new Date('Apr 01 2015') on my English system, in Chrome, with my machine being in the Eastern timezone, I get back Wed Apr 01 2015 00:00:00 GMT-0400 (Eastern Daylight Time) which is exactly what I want.
However, I am not sure if this (3-letter English month abbreviation) (2-digit date) (4-digit year) format is guaranteed to be interpreted in the same way regardless of browser and browser/OS locale/language.
Will this format work the same way across different (reasonably modern) browsers and locales? If not, then is there some other format that will work?
Please note that ISO-8601 doesn't answer this question. ISO-8601 date-only strings are interpreted as being in UTC, and not in local time, so new Date('2015-04-01') is interpreted as Tue Mar 31 2015 20:00:00 GMT-0400 (Eastern Daylight Time), i.e. April 1 turns into March 31, which is not what I'm looking for.
I am looking for a date format (only year, month and day, no time component), that will be guaranteed to be interpreted as local time, in all reasonably modern browsers, when passed to the Date() constructor in JavaScript.
There isn't one. There are a number of formats that, in practice, are reliably parsed by all browsers in use however none of them are required by ECMA-262 to be supported by ECMAScript implementations.
There is one format, a version of ISO 8601, that is specified in ES5 and ECMAScript 2015 however dates without a time zone are to be treated as UTC in ES5 and "local" in ECMAScript 2015.
But that was seen by implementers as "breaking the web", so while some browsers implemented that for a while, they have now reverted to ES5 behaviour and treat a missing timezone as UTC.
A small change in format such as changing the separator from "-" to "/" causes a reversion to implementation dependent behaviour and may cause the date to be treated as UTC or local (though most seem to treat 2015/12/17 as local).
So if you want a guarantee, there isn't one. However, if you are prepared to write a 2 line function, you can parse an ISO 8601 like string reliably based on whatever time zone you like. If you want it to be treated as local (i.e. set to 00:00:00 and offset based on system settings), then:
function parseISOLike(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2])
}
document.write(parseISOLike('2015-12-17'));
will do the job (without checking for valid values) and allow the separator to be any non–digit, so 2015/12/17, 2015-12-17 and 2015.12.17 will all be correctly parsed.
Edit
Parts of the above have been edited thanks to input from Matt Johnson.

Why is moment.js allowing date with one digit year when using strict parsing?

I am using moment.js to parse a date. http://momentjs.com/docs/#/parsing/string-format/
This is to validate and convert the date to a format required by my database. In my testing I encountered this input date '6-4-3' which should not be valid with the given format.
moment('6-4-3','YYYY-MM-DD',true).isValid(); //returns true
The resulting date in the moment object is "Mon Apr 03 0006 ...". When I call isValid, it returns true. I think it should consider this date invalid because it has too few digits in the input for each part of the format string.
I added a regex.test in my code to ensure that the dates have the right number of digits, but I think this should be handled differently in moment.js when strict is true.
Is there something I'm missing here? Isn't this the point of strict parsing? Or is there a reason why this is the intended behavior?
This was a known issue for past versions of Moment.js: YYYY-MM-DD with 3 digit year returns true for isValid().
It was fixed in December 2013, and your code works as expected with the most recent version of the library. Version 2.3.1 was released in October 2013 and does not include this fix.

new Date() works differently in Chrome and Firefox

I want to convert date string to Date by javascript, use this code:
var date = new Date('2013-02-27T17:00:00');
alert(date);
'2013-02-27T17:00:00' is UTC time in JSON object from server.
But the result of above code is different between Firefox and Chrome:
Firefox returns:
Wed Feb 27 2013 17:00:00 GMT+0700 (SE Asia Standard Time)
Chrome returns:
Thu Feb 28 2013 00:00:00 GMT+0700 (SE Asia Standard Time)
It's different 1 day, the correct result I would expect is the result from Chrome.
Demo code: http://jsfiddle.net/xHtqa/2/
How can I fix this problem to get the same result from both?
The correct format for UTC would be 2013-02-27T17:00:00Z (Z is for Zulu Time). Append Z if not present to get correct UTC datetime string.
Yeah, unfortunately the date-parsing algorithms are implementation-dependent. From the specification of Date.parse (which is used by new Date):
The String may be interpreted as a local time, a UTC time, or a time in some other time zone, depending on the contents of the String. The function first attempts to parse the format of the String according to the rules called out in Date Time String Format (15.9.1.15). If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats.
To make the Date constructor not (maybe) use the local timezone, use a datetime string with timezone information, e.g. "2013-02-27T17:00:00Z". However, it is hard to find a format that is reliable parsed by every browser - the ISO format is not recognised by IE<8 (see JavaScript: Which browsers support parsing of ISO-8601 Date String with Date.parse). Better, use a unix timestamp, i.e. milliseconds since unix epoch, or use a regular expression to break the string down in its parts and then feed those into Date.UTC.
I found one thing here. It seems the native Firefox Inspector Console might have a bug:
If I run "new Date()" in the native Inspector, it shows a date with wrong timezone, GMT locale, but running the same command in the Firebug Extension Console, the date shown uses my correct timezone (GMT-3:00).
Noticed that FireFox wasn't returning the same result as Chrome. Looks like the format you use in kendo.toString for date makes a difference.
The last console result is what I needed:
Try using moment.js. It goes very well and in similar fashion with all the browsers. comes with many formatting options. use moment('date').format("") instead of New Date('date')

Categories