new Date parsing in javascript is different between safari and chrome



javascript string to time (7)

I have the following code

var c = new Date(Date.parse("2011-06-21T14:27:28.593Z"));
console.log(c);

On Chrome it correctly prints out the date on the console. In Safari it fails. Who is correct and more importantly what is the best way to handle this?


Answer #1

My similar issue was caused by Safari not knowing how to read the timezone in a RFC 822 time zone format. I was able to fix this by using the ISO 8601 format. If you have control of the date format I got this working with java's SimpleDateFormat "yyyy-MM-dd'T'HH:mm:ss.sssXXX" which produces for me ie. "2018-02-06T20:00:00.000+04:00". For whatever reason Safari can't read "2018-02-06T20:00:00.000+0400", notice the lack of colon in the timezone format.

// Works
var c = new Date("2018-02-06T20:00:00.000+04:00"));
console.log(c);

// Doesn't work
var c = new Date("2018-02-06T20:00:00.000+0400"));
console.log(c);

Answer #2

I use the following function for parsing dates with timezone. Works fine both Chrome and Safari:

function parseDate(date) {
  const parsed = Date.parse(date);
  if (!isNaN(parsed)) {
    return parsed;
  }

  return Date.parse(date.replace(/-/g, '/').replace(/[a-z]+/gi, ' '));
}

console.log(parseDate('2017-02-09T13:22:18+0300'));  // 1486635738000 time in ms

Answer #3

You can't really use Date.parse. I suggest you use: new Date (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )

To split the string you could try

var s = '2011-06-21T14:27:28.593Z';
var a = s.split(/[^0-9]/);
//for (i=0;i<a.length;i++) { alert(a[i]); }
var d=new Date (a[0],a[1]-1,a[2],a[3],a[4],a[5] );
alert(s+ " "+d);

Answer #4

i tried converted date by truncating it and parsing it like that , its working fine with safari and ios .

var dateString = "2016-01-22T08:18:10.000+0000";
 var hours = parseInt(dateString.split("+")[1].substr("0","2"));
 var mins = parseInt(dateString.split("+")[1].substr("2"));
 var date = new Date(dateString.split("+")[0]);
 date.setHours(date.getHours()-hours);
 date.setMinutes(date.getMinutes()-mins);

Answer #5

I ended up using a library to offset this:

http://zetafleet.com/blog/javascript-dateparse-for-iso-8601

Once that library was included, you use this code to create the new date:

var date = new Date(Date.parse(datestring));

Our project wasn't using millisecond specifiers, but I don't believe that will cause an issue for you.


Answer #6

Instead of using 'Z' at the end of the date string, you can add the local client timezone offset. You'll probably want a method to generate that for you:

let timezoneOffset = () => {
    let date = new Date(),
        timezoneOffset = date.getTimezoneOffset(),
        hours = ('00' + Math.floor(Math.abs(timezoneOffset/60))).slice(-2),
        minutes = ('00' + Math.abs(timezoneOffset%60)).slice(-2),
        string = (timezoneOffset >= 0 ? '-' : '+') + hours + ':' + minutes;
    return string;
}

So the end result would be:

var c = new Date("2011-06-21T14:27:28.593" + timezoneOffset());


Answer #7

I've checked it in several browsers, and yes, safari returns invalid date. By the way, you don't have to use Date.parse here, just new Date([datestring]) will work too. Safari evidently requires more formatting of the datestring you supply. If you replace '-' with '/', remove the T and everything after the dot (.593Z), it will give you a valid date. This code is tested and works in Safari

var datestr = '2011-06-21T14:27:28.593Z'.split(/[-T.]/);
var safdat = new Date( datestr.slice(0,3).join('/')+' '+datestr[3] );

Or using String.replace(...):

new Date("2016-02-17T00:05:01+0000".replace(/-/g,'/').replace('T',' ').replace(/(\..*|\+.*/,""))




safari