Javascript JSON Date parse in IE7/IE8 returns NaN
Solution 1
In older browsers, you can write a function that will parse the string for you.
This one creates a Date.fromISO method- if the browser can natively get the correct date from an ISO string, the native method is used.
Some browsers got it partly right, but returned the wrong timezone, so just checking for NaN may not do.
Polyfill:
(function(){
var D= new Date('2011-06-02T09:34:29+02:00');
if(!D || +D!== 1307000069000){
Date.fromISO= function(s){
var day, tz,
rx=/^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
p= rx.exec(s) || [];
if(p[1]){
day= p[1].split(/\D/);
for(var i= 0, L= day.length; i<L; i++){
day[i]= parseInt(day[i], 10) || 0;
};
day[1]-= 1;
day= new Date(Date.UTC.apply(Date, day));
if(!day.getDate()) return NaN;
if(p[5]){
tz= (parseInt(p[5], 10)*60);
if(p[6]) tz+= parseInt(p[6], 10);
if(p[4]== '+') tz*= -1;
if(tz) day.setUTCMinutes(day.getUTCMinutes()+ tz);
}
return day;
}
return NaN;
}
}
else{
Date.fromISO= function(s){
return new Date(s);
}
}
})()
Result:
var start_time = '2012-06-24T17:00:00-07:00';
var d = Date.fromISO(start_time);
var month = d.getMonth();
var day = d.getDate();
alert(++month+' '+day); // returns months from 1-12
Solution 2
For ie7/8 i just did:
var ds = yourdatestring;
ds = ds.replace(/-/g, '/');
ds = ds.replace('T', ' ');
ds = ds.replace(/(\+[0-9]{2})(\:)([0-9]{2}$)/, ' UTC\$1\$3');
date = new Date(ds);
This replaces all occurrences of "-" with "/", time marker "T" with a space and replaces timezone information with an IE-friendly string which enables IE7/8 to parse Dates from Strings correctly. Solved all issues for me.
Solution 3
See RobG's post at Result of toJSON() on a date is different between IE8 and IE9+.
Below function worked for me in IE 8 and below.
// parse ISO format date like 2013-05-06T22:00:00.000Z
function convertDateFromISO(s) {
s = s.split(/\D/);
return new Date(Date.UTC(s[0], --s[1]||'', s[2]||'', s[3]||'', s[4]||'', s[5]||'', s[6]||''))
}
You can test like below:
var currentTime = new Date(convertDateFromISO('2013-05-06T22:00:00.000Z')).getTime();
alert(currentTime);
Solution 4
I suggest http://momentjs.com/ for cross browser date issues.
Solution 5
@gib Thanks for the suggestion on Moment.js. This small library really helps out with dealing with dates and JavaScript.
Moment.js solved the problem described in the original question that I was also having. IE8 was displaying JSON ISO dates as NaN when parsed into a new Date() object.
Quick solution (include moment.js in your page, or copy the code to your js functions include)
If you just need to display a date on your page, loaded from a JSON ISO date, do this:
order_date = moment(data.OrderDate); //create a "moment" variable, from the "data" object in your JSON function in Protoype or jQuery, etc.
$('#divOrderDate).html(order_date.calendar()); //use Moment's relative date function to display "today", "yesterday", etc.
or
order_date = moment(data.OrderDate); //create a "moment" variable, from the "data" object in your JSON function in Protoype or jQuery, etc.
$('#divOrderDate).html(order_date.format('m/d/YYYY')); //use Moment's format function to display "2/6/2015" or "10/19/2014", etc.
If you must have a Date() object (say for use with jQuery Components), do the following so successfully populate your JSON provided ISO date. (This assumes you are already inside the function of handling your JSON data.)
var ship_date = new Date(moment(data.ShipDate).format('m/d/YYYY')); //This will successfully parse the ISO date into JavaScript's Date() object working perfectly in FF, Chrome, and IE8.
//initialize your Calendar component with the "ship_date" variable, and you won't see NaN again.
Josiah
Updated on December 07, 2020Comments
-
Josiah over 3 years
I'm parsing a date from a JSON event feed - but the date shows "NaN" in IE7/8:
// Variable from JSON feed (using JQuery's $.getJSON) var start_time = '2012-06-24T17:00:00-07:00'; // How I'm currently extracting the Month & Day var d = new Date(start_time); var month = d.getMonth(); var day = d.getDate(); document.write(month+'/'+day);// "6/24" in most browsers, "Nan/Nan" in IE7/8
What am I doing wrong? Thanks!
-
segFault about 11 yearsThis is returning 5/24 in IE8 instead of 6/24 can you please update the function to work properly???
-
kennebec about 11 yearsDidn't change the function, just ++incremented the date.getMonth() in the alert to return a 1 based month.
-
jackocnr almost 11 yearsThis works great, thanks you. Would really appreciate it if you could comment the code a bit to help us understand why you've done certain things e.g. +D!==1307000069000
-
Dzmitry Lazerka over 10 yearsNope, it will return different date instances. Compare
new Date('2013/01/01')
in Chrome and in IE8. The correct would benew Date('2013-01-01Z)
(note Z at the end). -
fbtb over 10 yearsmention "For ie7/8" in my previous post.
-
Dzmitry Lazerka over 10 yearsYou're right, 'Z' matters only when slashes are used in Chrome, sorry. We just do replace dashes with slashes in all browsers to avoid browser detection. So we need 'Z`.
-
visum about 10 years@jackocnr That took me a minute, too. The + casts D to a number. If it's a valid date, it's the same as D.getTime(), or 1307000069000. Otherwise, NaN. Not terribly readable, but clever.
-
Gurpreet Singh about 10 yearsi was facing the same problem with IE8, .replace('-', '/') solved the issue. Thanks a lot !
-
Mike Gledhill over 9 yearsNope. In IE8, this gave me a string of "2015/01/12T08:05:02.68", which it convert into a "Invalid Date" value.
-
Aaron Breckenridge over 9 yearsHeads up, this doesn't work for the date as formatted in the question. You must use the
00.000Z
format for timestamps, the-07:00
in the question wont work. -
Estin Chin about 9 years@breckenedge, you are right. It must use ISO format
00.000Z
-
Nicholas E. almost 9 yearsThe regex should be updated to: rx=/^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|([+\-])(\d\d):?(\d\d))?$/ Adding the question mark after the last colon, making it optional. The timezone offset often does not include the colon. (ex: "-400", "+0000") This is the format in PHP for the constant DateTime::ISO8601 yields no colon.
-
The Dembinski over 7 yearsmoment.js is a decent option. My issue is the size, so much of its girth is dedicated to handling things I dont care about. (eg. hebrew characters in date-time stamps)
-
Szymon over 7 yearsthaaaaaaanks :)