Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Result of toJSON() on a date is different between IE8 and IE9+

I'm doing a conversion from Date to string and back for using in sessionStorage. so I first do this:

sessionStorage.currentDate = myDate.toJSON();

and then I do this:

if (sessionStorage.currentDate ) {
    myDate = new Date(sessionStorage.currentDate);
}

The problem is that the myDate.toJSON() function in IE9+ returns "2013-05-06T22:00:00.000Z" but in IE8 it returns "2013-05-06T22:00:00Z" missing the decimal part at the end.

The fact is that in IE8 is failing the subsequent re-conversion into a date (the result from new Date(sessionStorage.currentDate) is NaN)

Any idea why this is happening and how to make this code work for IE8+?

Update:

I tried to replace the string in debug, and it turns out that none of the 2 strings works. So it actually seems to be a problem of the new Date(sessionStorage.currentDate) not recognizing the format (which is UTC)

like image 693
Maurizio In denmark Avatar asked Jul 11 '13 11:07

Maurizio In denmark


2 Answers

Prior to ES5, parsing of dates was entirely implementation dependent. IE 8 (and lower) won't parse the ISO 8601 format specified in ES5, so just parse it yourself:

// parse ISO format date like 2013-05-06T22:00:00.000Z
function dateFromISO(s) {
  s = s.split(/\D/);
  return new Date(Date.UTC(s[0], --s[1]||'', s[2]||'', s[3]||'', s[4]||'', s[5]||'', s[6]||''))
}

Assumes the string is UTC.

like image 155
RobG Avatar answered Oct 15 '22 11:10

RobG


I don't believe the different number of places is a case of something 'not working'. From https://en.wikipedia.org/wiki/ISO_8601#Times:

Decimal fractions may also be added to any of the three time elements. [...] A fraction may only be added to the lowest order time element in the representation. To denote "14 hours, 30 and one half minutes", do not include a seconds figure. Represent it as "14:30,5", "1430,5", "14:30.5", or "1430.5". There is no limit on the number of decimal places for the decimal fraction. However, the number of decimal places needs to be agreed to by the communicating parties.

Therefore, as toJSON converts a time to ISO-8601 format, and both strings you mention are valid ISO-8601, it appears that both are correct - they just happen to be different.

In terms of a fix, a simple regex replace should do the trick - replace all matches for \.\d+Z with just Z (I'm assuming you don't need millisecond-level accuracy!). This should give you a string that works on IE8 even if it was generated from IE9

like image 40
Adrian Wragg Avatar answered Oct 15 '22 11:10

Adrian Wragg