Search code examples
javascriptdatesafari

Invalid date in safari


 alert(new Date('2010-11-29'));

chrome, ff doesn't have problems with this, but safari cries "invalid date". Why ?

edit : ok, as per the comments below, I used string parsing and tried this :

alert(new Date('11-29-2010')); //doesn't work in safari
alert(new Date('29-11-2010')); //doesn't work in safari
alert(new Date('2010-29-11')); //doesn't work in safari

edit Mar 22 2018 : Seems like people are still landing here - Today, I would use moment or date-fns and be done with it. Date-fns is very much pain free and light as well.


Solution

  • The pattern yyyy-MM-dd isn't an officially supported format for Date constructor. Firefox seems to support it, but don't count on other browsers doing the same.

    Here are some supported strings:

    • MM-dd-yyyy
    • yyyy/MM/dd
    • MM/dd/yyyy
    • MMMM dd, yyyy
    • MMM dd, yyyy

    DateJS seems like a good library for parsing non standard date formats.

    Edit: just checked ECMA-262 standard. Quoting from section 15.9.1.15:

    Date Time String Format

    ECMAScript defines a string interchange format for date-times based upon a simplification of the ISO 8601 Extended Format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ Where the fields are as follows:

    • YYYY is the decimal digits of the year in the Gregorian calendar.
    • "-" (hyphon) appears literally twice in the string.
    • MM is the month of the year from 01 (January) to 12 (December).
    • DD is the day of the month from 01 to 31.
    • "T" appears literally in the string, to indicate the beginning of the time element.
    • HH is the number of complete hours that have passed since midnight as two decimal digits.
    • ":" (colon) appears literally twice in the string.
    • mm is the number of complete minutes since the start of the hour as two decimal digits.
    • ss is the number of complete seconds since the start of the minute as two decimal digits.
    • "." (dot) appears literally in the string.
    • sss is the number of complete milliseconds since the start of the second as three decimal digits. Both the "." and the milliseconds field may be omitted.
    • Z is the time zone offset specified as "Z" (for UTC) or either "+" or "-" followed by a time expression hh:mm

    This format includes date-only forms:

    • YYYY
    • YYYY-MM
    • YYYY-MM-DD

    It also includes time-only forms with an optional time zone offset appended:

    • THH:mm
    • THH:mm:ss
    • THH:mm:ss.sss

    Also included are "date-times" which may be any combination of the above.

    So, it seems that YYYY-MM-DD is included in the standard, but for some reason, Safari doesn't support it.

    Update: after looking at datejs documentation, using it, your problem should be solved using code like this:

    var myDate1 = Date.parseExact("29-11-2010", "dd-MM-yyyy");
    var myDate2 = Date.parseExact("11-29-2010", "MM-dd-yyyy");
    var myDate3 = Date.parseExact("2010-11-29", "yyyy-MM-dd");
    var myDate4 = Date.parseExact("2010-29-11", "yyyy-dd-MM");