11

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)

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Maurizio In denmark
  • 4,226
  • 2
  • 30
  • 64

3 Answers3

12

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.

Cees Timmerman
  • 17,623
  • 11
  • 91
  • 124
RobG
  • 142,382
  • 31
  • 172
  • 209
  • This is actually what Iøm already doing for dates coming from wcf web services, so I already have the function. wasn't expectiong to need it for dates I converted myself. I'm gonna try if my function works and then I'll accept this answer. – Maurizio In denmark Jul 11 '13 at 12:37
  • I would recommend storing just the time value, then you just do `new Date(timeValue)`. There's no point in creating a formatted string that will need to be parsed to be useful anyway. – RobG Oct 15 '13 at 05:59
2

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

Adrian Wragg
  • 7,311
  • 3
  • 26
  • 50
  • 1
    I know it's allowed but the conversion just return NaN in ie8 and I canøt explain why. I don't see the proposed solution fro m zerkms – Maurizio In denmark Jul 11 '13 at 12:18
  • The time with the .000 is a perfectly valid representation, but just not one that IE8 understands, hence you getting NaN. The proposed solution I originally mentioned has unfortunately been deleted, so I've added one of my own instead. – Adrian Wragg Jul 11 '13 at 12:24
  • I added an update after trying your solution. I think the problem is different thatn what I thought initially – Maurizio In denmark Jul 11 '13 at 12:28
  • It is, yes - take a read of http://stackoverflow.com/questions/5802461/javascript-which-browsers-support-parsing-of-iso-8601-date-string-with-date-par for solutions to the new problem. – Adrian Wragg Jul 11 '13 at 12:32
  • @MaurizioIndenmark Do you need to store the dates as JSON format? Ticks or similar are more portable between platforms, and avoid workarounds. – Adrian Wragg Jul 11 '13 at 12:42
  • No I need to save the dates into a sessionStorage that is only string, and then re-casting it into a string – Maurizio In denmark Jul 11 '13 at 12:55
  • 1
    Your ticks could be strings too. Or, store your date in yyyy-mm-dd hh:mm:ss format. Basically, you're using a date format that is only supported in a subset of browsers; I'm just suggesting you consider using a format with wider support, and avoiding hacky workarounds. – Adrian Wragg Jul 11 '13 at 13:07
  • I thought the toJson was the best way. bu I don't care how I will save the date, as long as I can recover it later on. all in UTC – Maurizio In denmark Jul 11 '13 at 13:17
-2

I think you need to IE8 specific browser hack for this. And for this need to extra code like...

if(jQuery.browser.msie && jQuery.browser.version.substring(0, 1) == 8) {
    // add extra missing zero
}
sib10
  • 1,104
  • 1
  • 9
  • 15
  • May be, it is better to use a "feature detection? Something like so if (new Date("2013-12-31T00:00:00.000Z") === NaN) { window.paseDateEx = function(str) { /* manual parsing*/ }; } else { window.parseDateEx = function (str) { return new Date(str); } } – Konstantin Isaev Dec 13 '13 at 12:49