Date.parse error

Date.parse error

johnwillynjohnwillyn Posts: 14Questions: 0Answers: 0
edited January 2014 in Plug-ins
I am seeing some odd behavior with Date.parse() in Chrome, and doing some research, there are some who think this is expected behavior.

Date.parse("$245.12") returns -54406839600000.

This affects the automatic type detection because I added a currency detection method with a 'push' to the aTypes array, so the result comes back as a 'date' for the above example before it can detect it as a 'currency'.

My workaround was to add the currency detection function at the head of the aTypes array with an unshift instead, but it seems like Date.parse can't be relied upon in some cases.

Thoughts?

Replies

  • allanallan Posts: 57,686Questions: 1Answers: 9,195 Site admin
    Wow - that's not so good. I think I'd be relying upon that returning NaN / null. Indeed, I am since that is what DataTables does...

    You could try DataTables 1.10 as it have currency sorting / detection built in ( http://datatables.net/download - pre-beta currently) but I rather suspect that is going to fall into the same trap.

    I may have to add some extra cdd to DataTables to catch such a case, which I'm loth to do, but it looks like it might be unavoidable. Did you find any discussions on the web above this behaviour from Chrome? If it is limited to $ that I guess it is a simple workaround, but I suspect it won't be...

    Allan
  • johnwillynjohnwillyn Posts: 14Questions: 0Answers: 0
    Hi Allan,

    Sorry I did not get back on this sooner...I have been consumed evaluating Datatables and Editor. I am impressed!

    I don't have a lot of different browsers loaded up, but I did test this in Safari this morning, and the same expression of Date.parse("$245.12") returns the expected NaN.

    I would say this is probably an over-optimistic parser in Chrome.

    I did find the following discussion threads, in which some claim it is 'expected' based on the 'crazy input'.

    https://code.google.com/p/datejs/issues/detail?id=164

    A slightly more informed thread, and I suspect this could be classified a 'bug' in Chrome because there is a standard for date strings, and currency strings are not in it.

    http://stackoverflow.com/questions/8266710/javascript-date-parse-difference-in-chrome-and-other-browsers

    Thanks for the great work. I will send feedback, and I have one business question that I will follow up on separately.

    JohnL
  • allanallan Posts: 57,686Questions: 1Answers: 9,195 Site admin
    Thanks very much for the feedback. Its been a while since I've dug around big library code, but I think I'll take a look to see what Chrome is doing here. Will post back when I have more info.

    I look forward to hearing from you with any other questions you might have :-)

    Regards,
    Allan
  • allanallan Posts: 57,686Questions: 1Answers: 9,195 Site admin
    I've been digging into this a little bit more, and the v8 date parser has a very useful comment describing what is happening: https://code.google.com/p/v8/source/browse/trunk/src/dateparser-inl.h#72

    > Any unrecognized word before the first number is ignored.

    So, what is happening is that the `$` in your string is being ignored and Chrome is just parsing `245.12` which it is a December (12) in the year 245.

    To fix fully, and safely in Chrome, I'd need to check against the first word, if there is one, in the string - which are things like `Thu` and `Feb` etc. However, a shorter workaround is:

    [code]
    d && d.charAt && d.charAt(0).match(/[\d\+\-a-zA-Z]/)
    [/code]

    i.e. take the first character and check if it is a number, +/- (ISO 8601 which ES5 implements allows a leading ±), or a roman alphabet character.

    If that passes then use the return from Date.parse as before, otherwise it can't be a date.

    I don't really see any problem including this in DataTables, but I'll have a little think about it before committing. The own two downsides are that its an extra few bytes (when I'm trying really hard to keep the size down) and it will take fractionally longer to parse the string.

    Regards,
    Allan
  • allanallan Posts: 57,686Questions: 1Answers: 9,195 Site admin
    Discovered one other fun point, `Date.parse` will treat the numbers 1-12 as a month if passed on their own, 13-31 return NaN and 32+ are treated as years... Little bit odd that imho, but so it goes :-).

    Therefore, I've just committed a fix which gives the numeric type detection a higher priority that date, and the change from my last post to fix Date.parse detecting currency as a date.

    Change set:
    https://github.com/DataTables/DataTablesSrc/commit/5fd86f5

    And built in the build repo:
    https://github.com/DataTables/DataTables/tree/master/media/js

    Thanks again for flagging this up!

    Allan
  • johnwillynjohnwillyn Posts: 14Questions: 0Answers: 0
    Wow, that is quite an analysis for what seems like a Chrome-specific behavior. Thanks for your thorough and thoughtful approach! I assume this will be in 1.10.

    JohnL
  • allanallan Posts: 57,686Questions: 1Answers: 9,195 Site admin
    It certainly will be :-). You can grab the latest from the github address above should you fancy giving it a whirl just now.

    Allan
This discussion has been closed.