4

Referencing to the accepted answer on this question How do I get the number of days between two dates in JavaScript?. I see, in the function parseDate:

function parseDate(str) {
    var mdy = str.split('/')
    return new Date(mdy[2], mdy[0]-1, mdy[1]);
}

He is doing this:

var mdy = str.split('/')
return new Date(mdy[2], mdy[0]-1, mdy[1]);

i.e. splitting the passed date into month, day and year and then passing it on to Date like new Date(year, month, day) while he could simply do new Date(str) and it would have returned the same result (Wouldn't it?). Can anyone please explain the difference between both the ways?

Update: Test results:

var str = '1/1/2000'
var mdy = str.split('/')
console.log( new Date(str) ) // Sat Jan 01 2000 00:00:00 GMT+0500 (Pakistan Standard Time)
console.log( new Date(mdy[2], mdy[0]-1, mdy[1]) ); // Sat Jan 01 2000 00:00:00 GMT+0500 (Pakistan Standard Time)
Community
  • 1
  • 1
Kamran Ahmed
  • 11,809
  • 23
  • 69
  • 101
  • 1
    No, they're not the same, even assuming you'll subtract one month later (he's doing `mdy[0]-1`), because new `Date(str)` is required (by standard) to accept only date in a specific format (year/month/day, see also [this post](http://stackoverflow.com/a/17734119/1207195)) and there **they're parsing using a specific locale rules** (month/day/year). To be honest I wouldn't even use that code for parsing (because yes, actually it'll be broken for a different locale). – Adriano Repetti Sep 16 '14 at 09:28
  • According to your update: you're using 1/1/200 then you won't see a difference but browser must accept (for parsed date) only what it produce when converting to string and they yyyy/mm/dd format. Try with 13/1/2014...it depends on locale (then it'll fail for locales where month comes first). – Adriano Repetti Sep 16 '14 at 09:35
  • @LearningNeverStops yes because your locale matches what they're doing with manual parsing. It'll fail for example in my locale (Italian/Italy) because we write day/month/year (then, for example, "21 December 2014" is "21/12/2014" but their parsing routine expects "12/21/2014" and conversion will obviously fail). Usually I always strongly suggest to do not do date parsing manually in JavaScript, it's a complex topic and there are some pretty nice libraries. – Adriano Repetti Sep 16 '14 at 09:37

2 Answers2

1

No, they're not the same (even assuming you'll subtract one month later: he's doing mdy[0] - 1) because new Date(str) is required (by standard, see §15.9.4.2) to accept only date in a specific format ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ, see also this post, I won't repeat myself here):

If the String does not conform to that format [ISO 8601] the function may fall back to any implementation-specific heuristics or implementation-specific date formats.

Please note (as pointed out by Royi in comments) that also RFC 2822 should be supported (according to MDN) but it's not mentioned in JavaScript specifications and Internet Explorer doesn't officially support it (see MSDN, it can parse something similar but it's not the same).

In that code they're parsing using a specific locale rules (MM/DD/YYYY, I suppose en-US locale but it's not only one). To be honest I wouldn't even use that code for parsing (because yes, actually it'll be broken for a different locale: even separator used for splitting is not "locale safe"). Let me explain with an example:

  • You're using a proper configured date time picker (or <input type="date"/> when supported) you'll enter date according to your locale. For example in Italy (but in general in Europe) we write DD/MM/YYYY.
  • Now let's imagine that user picked 21 December 2014 (formatted as 21/12/2014 according to his locale).
  • With string splitting that code will fail (because it'll pick 21 as month number, obviously it's not valid). Even worse than that such errors may even go unnoticed (for example if user picks 1/2/2014 code will "think" it's 2nd Jan but user picked 1st Feb). Do you want to make it more complicate? Even new Date(str) may fail because it's browser dependent (and you can't really trust heuristic to be portable and safe).

If you're asking yourself "Then why they used such code?" I'd say that they used a quick workaround to support dates using en-US locale (probably because browser they used didn't support them with heuristic guess) but it's not something you should reuse.

Solution? Do not ever parse date by hand (unless you really and deep know what you're doing), use a good library (for example moment.js) for that because most assumption you may do about date formatting are...wrong.

Community
  • 1
  • 1
Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
  • _to accept **only** date in a specific format ISO 8601_ —incorrect. it will accept also other formats. it will first try iso , but then try heuristics . Also : this format will yield always local results ( and it's not iso) `new Date("2013/07/27 10:10:10") ` – Royi Namir Sep 16 '14 at 10:02
  • @RoyiNamir well strictly speaking (see quoted paragraph from standard) it's **required** to parse ISO 8601 and it **may** fall back to [...]. That's why I wrote "required" but I posted quote too. That format works (AFAIK) on _most_ browsers but it's not standard and not supported in all older browsers... – Adriano Repetti Sep 16 '14 at 10:04
  • [Also](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) : _dateString A string representing an **RFC2822** or **ISO 8601** date (other formats may be used, but results may be unexpected)._ so it can handle also rfc support – Royi Namir Sep 16 '14 at 10:06
  • @RoyiNamir but RFC2822 it's **not supported by IE** (not surprising, I admit): [MSDN](http://msdn.microsoft.com/en-us/library/ie/ff743760(v=vs.94).aspx) (see section _Other Data Formats_) and it's **not mentioned in JavaScript specifications**. – Adriano Repetti Sep 16 '14 at 10:30
  • http://chat.stackoverflow.com/rooms/61331/room-for-royi-namir-and-adriano-repetti – Royi Namir Sep 16 '14 at 10:31
  • If I recall correctly, `MM/DD/YYYY` is actually the only format that is equivalently supported by all browsers. Only it uses the local timezone, i.e. doesn't work well when you want UTC. – Bergi Sep 16 '14 at 12:21
  • @Bergi yes, probably it's supported by all _major_ browsers but I'd refrain to use it because if user writes (or we build a string) "1/2/2015" then there is too much _heuristic_ there. What browser will understand? Well-known "MM/DD/YYYY" or locale "DD/MM/YYYY"? For two digits years like now what "12/1/14" is? IMO too much uncertain and even if it works on _our_ browser with _our_ locale then we simply can't predict what will happen with another browser or even just another locale... – Adriano Repetti Sep 17 '14 at 07:08
  • @AdrianoRepetti: I thought that all browser vendors use the odd US format independent from the locale, for compatibility reasons. But maybe I've confused it with `YYYY/MM/DD` to be universely supported; I'm not sure any more. – Bergi Sep 17 '14 at 13:12
  • @Bergi I remember there are issues with Safari, Chrome, IE and FF AFAIK understand it. Other browser...I don't want to guess. Problem anyway is that it's not standard, if I write "1/2/14" (with that code snippet) browser may correctly assume it's DD/MM because it's standard format it produces - according to user locale settings - for a date (and this is mandatory for §15.9.4.2). In this case if date is invalid it'll go with MM/DD. THat's why I was suggesting to avoid such custom formatting/parsing if code doesn't also handle locale settings properly. – Adriano Repetti Sep 17 '14 at 14:27
  • Two-digit years are yet another format, with different rules :-) I only remember there was a format with slashes for dates which worked quite consistent across browsers, it might be different from than the one in question though. – Bergi Sep 17 '14 at 14:39
  • @Bergi yes MM/DD/YYYY is recognized by many browsers (I doubt Safari, at least older versions) but it's not standard. What I mean is: if you write "1/2/2014" then browsers (§15.9.4.2 because probably default toString respects that) _should_ first parse it according to user locale. It's not true for Chrome and IE but, for example, FF does it (and anyway it can't recognize such format). Such basic task and such mess... – Adriano Repetti Sep 17 '14 at 14:58
-1

I tried to enter your test code into jsperf.com, and the results on my machine are clear, and they say that you should not try to split the string.

I tried two tests for the test using a split string, and supprisingly, the split itself was not what was taking up the time.

Try for yourself at http://jsperf.com/date-from-string-or-dateparts

Dimse
  • 1,476
  • 1
  • 10
  • 15
  • 1
    It's not a problem about timing (in general I'd go with what it's more clear and concise, users won't note any difference in such code) but correctness... – Adriano Repetti Sep 16 '14 at 09:43