3

I'm having trouble parsing dates for my website. It used to work fine on both IE and Chrome (I haven't tried Firefox yet). But recently I have been unable to parse dates on chrome.

The date string which I obtain from the database looks like this "Oct 17 2016 12:00AM"

Here is the code I'm using to debug my problem

console.log("String = "+item.DueDate);
console.log("new Date = " + new Date(item.DueDate));
console.log("Date Parse = " + Date.parse(item.DueDate));
console.log("Moment Parse = " + moment(item.DueDate));

Here is what is returned by IE:

String = Oct 17 2016 12:00AM
new Date = Mon Oct 17 2016 00:00:00 GMT-0400 (Eastern Daylight Time)
Date Parse = 1476676800000
Moment Parse = 1476676800000

And here is what is returned by Chrome:

String = Oct 17 2016 12:00AM
new Date = Invalid Date
Date Parse = NaN
Moment Parse = NaN

I use Date.parse() in one of my function that finds the difference between to dates:

function daydiff(first, second) {
    return Math.round((second - first) / (1000 * 60 * 60 * 24));
}

var dif = daydiff(Date.parse(item.DueDate), Date.parse(item.DateShipped));

What should I do to my date string in order for it to work with both chrome and internet explorer?

Fixed

So I fixed it by changing my web api call to return a DateTime rather than string.

Mark
  • 768
  • 3
  • 8
  • 26
  • Is the date being stored as a string or an integer? – Adam Buchanan Smith Aug 19 '16 at 20:12
  • It's stored in the database as a string. – Mark Aug 19 '16 at 20:15
  • 5
    Cross browser issues are common when parsing values. Your best bet is to use a library like moment.js to do the parsing, it has taken most, if not all, of the browser variables into account. Also, that is not the way you want your date times to look like when they come from the server. You might want to improve how they are being stored. – QBM5 Aug 19 '16 at 20:20
  • 2
    It looks like chrome doesn't like the AM/PM part, could you format the date server side as UTC before sending it back to the browser? Better yet, I would suggest only ever storing dates as UTC in your DB. – fyrb Aug 19 '16 at 20:22
  • moment js did not work. I do not need the time so I will try to parse just the date. Anyone have any suggestions on how they would do that? – Mark Aug 19 '16 at 20:31
  • 2
    Storing dates as strings in your database is a bad idea, sql queries are down right impossible when you don't have a database with proper datetime columns. – seahorsepip Aug 19 '16 at 20:34
  • It's due to some legacy code that a previous developer left. Do you have any suggestions or documentation on converting the entire column from a string to a DateTime? – Mark Aug 19 '16 at 20:36
  • Okay so I fixed it by parsing the Date on the back end and then returning a DateTime object to my Get request. – Mark Aug 19 '16 at 20:50
  • 1
    @QBM5; It should be noted that recent versions of moment.js require you to pass a format string when parsing dates from strings, precisely because of cross browser issues. – Heretic Monkey Aug 19 '16 at 20:52
  • 1
    if i add a space, this works in chrome `new Date("Oct 17 2016 12:00 AM")` – Veas Aug 19 '16 at 20:57

1 Answers1

2

Never parse strings with the Date constructor (or Date.parse, they are equivalent for parsing) as it is almost entirely implementation dependent. Even the one format specified in ECMA-262 is not reliably parsed by all browsers in use.

Use a bespoke function or a library that provides parsing and formatting and always pass the format to parse to the parser. Suitable libraries are moment.js, date.js and fecha.js, but there are many others.

A bespoke function might look like:

function parseSpecia(s) {
    var months = {jan:0,feb:1,mar:2,apr:3,may:4,jun:5,jul:6,aug:7,sep:8,oct:9,nov:10,dec:11};
    var h;
    if (/a[mp]$/i.test(s)) {
        h = /am$/i.test(s)? 0 : 12;
        s = s.replace(/a[mp]$/i,'');
    }
    var b = s.split(/[ :]/)
    return new Date(b[2], months[b[0].toLowerCase().substr(0,3)], b[1],(b[3]%12)+h, b[4]);
}

var s = 'Oct 17 2016 12:00AM';
console.log(parseSpecia(s));

Whereas using a library would look like:

fecha.parse('Oct 17 2016 12:00AM','MMM DD YYYY hh:mm:zz');
RobG
  • 142,382
  • 31
  • 172
  • 209