0

I am trying to parse a date in safari so that my website will be compatible with IOS as well as everything else, but when I parse a date, it only returns NaN.

The date that I am trying to parse looks like this: "2015-06-29T23:59:59"

I've looked around for different ways to do this, but I still haven't found a solution to this problem.

Is there anyone who knows a function that will parse the date in safari or a work-around to this problem?

The original approach was: Date.parse("2015-06-29T23:59:59");

Thanks.

Tomzter
  • 33
  • 1
  • 5

2 Answers2

1

The only reliable way to parse a date string is to do it manually, do not rely on Date.parse or passing strings to the Date constructor (which is essentially the same thing).

Before ECMAScript ed 5 (ES5), parsing of strings was entirely implementation dependent. ES5 specified various ISO formats, however there were further changes to parsing with ed 6, so even ISO formats are unreliable and may return local, UTC or NaN dates.

The string "2015-06-29T23:59:59" will be parsed as UTC under ES5, local under ed 6 and before then anything goes (IE8 returns NaN, other browsers from that era may too).

A simple parser, assuming es 6 behaviour and local timezone is:

function parseISO(s) {
  var b = s.split(/\D/);
  return new Date(b[0], b[1]-1, b[2], b[3], b[4], b[5]);
}

Validating the values and ensuring 2 digit years requires a couple more lines:

function parseISO(s) {
  var b = s.split(/\D/);
  var d = new Date(b[0], b[1]-1, b[2], b[3], b[4], b[5]);
  d.setFullYear(b[0]);
  return d && d.getMinutes() == b[4] && d.getMonth() == b[1]-1 && d.getDate() == b[2]? d : new Date(NaN);
}
RobG
  • 142,382
  • 31
  • 172
  • 209
-2

According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse safari should work with

Date.parse("2015-06-29T23:59:59");

Perhaps post a code snippet that returns NaN, you may be doing something wrong

Having said that, the following may help if safari in IOS is different to the safari referred to in the MDN article

function parseDate(s) {
    var dateTime = s.split('T');
    var dateBits = dateTime[0].split('-');
    var timeBits = dateTime[1].split(':');
    return new Date(dateBits[0], parseInt(dateBits[1]) - 1, dateBits[2], timeBits[0], timeBits[1], timeBits[2]).valueOf();
}

parseDate("2015-06-29T23:59:59");

Returns the same value as

Date.parse("2015-06-29T23:59:59");

In firefox, so, that's a start I guess

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • 1
    fair enough, I'll go and buy an iPhone just to find out why safari sux :p – Jaromanda X Jun 30 '15 at 12:33
  • That worked in Chrome, FF, safari and IE! Thank you so much! – Tomzter Jun 30 '15 at 12:47
  • I want to add that even though the function worked, the result is going to turn out wrong because the function returns a value that is 20 hours(7200000ms) larger than what a regular Date.parse() would do. So I modified it to not subtract 1, but rather subtract 7180hours in the end: return (new Date(dateBits[0], parseInt(dateBits[1]), dateBits[2], timeBits[0], timeBits[1], timeBits[2]).valueOf() - 2584800000); I pick 7180hours because that is the difference between the real answer if I DON'T include the "- 1" after parseInt(dateBits[1]) – Tomzter Jun 30 '15 at 13:51
  • Don't do that, month should be 1 less than the passed in value. because month is zero based - i.e. January = 0 not 1 - not sure why you're getting 7200000ms (that's 2 hours not 20) difference – Jaromanda X Jun 30 '15 at 13:58
  • Yeah, I miscalculated the hours, sorry about that. I re-added the "-1" and removed the " - 2584800000". It still works and still finds the correct time-period in the xml document I am reading from, but that is because the time spand is 6 hours so 2 hours wont make a difference. It is still showing a 2 hour difference when contrasted with Date.parse(ISO8601time) and this might cause problems for others who uses the function, but have a narrower time spand. Anyways, thank you a lot, you've been great at helping. – Tomzter Jun 30 '15 at 14:38
  • @Tomzter— **don't use Date.parse**, see the other answer for why not. The string you are passing might be treated as local, UTC or NaN, all of which are compliant with various versions of ECMA-262 (so don't go blaming the browsers). – RobG Jun 30 '15 at 22:28
  • It only seemed browser specific to me when the only browser(so far) that didn't return what I expected was safari, but thanks, I understand now. – Tomzter Jul 01 '15 at 07:11