Overflew
Overflew

Reputation: 8162

JSDate - Parse a ddMMyyyy format date correctly

I've having trouble with parsing user input with Javascript, where I can't get the parser to accept dates in ddMMyyyy correctly. It parses correctly when there are separator characters.

The example below is using DateJS (NZ localised), and I've had an initial attempt with the newer MomentJs (which isn't proving ideal for input validation). I'm open to other frameworks, if they're going to handle input cases adequately.

My test cases:

// Parses correct value
var dateWithHyphens = Date.parse('01-06-2012');

// Parses incorrectly, using MMddyyy, instead of ddMMyyyy
var dateWithoutHyphens = Date.parse('01062012');

// Parses incorrectly, using MMddyyy, instead of ddMMyyyy
var dateWithFormat = Date.parse('01062012', { format: 'ddMMyyyy'});

I've created a JSFiddle for this: http://jsfiddle.net/ajwxs/1

The test cases should return 1 June, but the incorrect ones return Jan 06. (That this is input parsing - output formatting is too late).

Any suggestions on if JSDate can be better prodded to use the correct format for parsing those dates?

Update

In this application, I'm validating a number of possible user inputs, including:

01062012
01/06/2012
010612

This would make an implementation of a parseExact-style implementation a bit verbose...

Upvotes: 1

Views: 3968

Answers (2)

Stephenr
Stephenr

Reputation: 101

You want to use the Date.parseExact method. For some reason it works while the normal parse does not. Also you don't need to pass the format option wrapped in an object.

According to the spec Date.parse is not supposed to take a format option so that is probably why.

// Parses correctly
var dateWithFormat = Date.parseExact('01062012', 'ddMMyyyy');

I have also updated the jsfiddle to be sure.

Update

I think the issue is that the parser hard-codes a bunch of simple formats and those override the localization setting for the date, month and year order in some cases. If you put the following before where you use Date it will fix your issue.

Date.Grammar._formats = Date.Grammar.formats([
    "\"yyyy-MM-ddTHH:mm:ssZ\"",
    "yyyy-MM-ddTHH:mm:ssZ",
    "yyyy-MM-ddTHH:mm:ssz",
    "yyyy-MM-ddTHH:mm:ss",
    "yyyy-MM-ddTHH:mmZ",
    "yyyy-MM-ddTHH:mmz",
    "yyyy-MM-ddTHH:mm",
    "ddd, MMM dd, yyyy H:mm:ss tt",
    "ddd MMM d yyyy HH:mm:ss zzz",
    "ddMMyyyy",
    "MMddyyyy",
    "ddMyyyy",
    "Mddyyyy",
    "dMyyyy",
    "Mdyyyy",
    "yyyy",
    "dMyy",
    "Mdyy",
    "d"
]);

This is not pretty but it is definitely shorter than listing all of the possible options, if only by a little bit. If you can find a less quirky Date library that might be a better option.

Upvotes: 1

nnnnnn
nnnnnn

Reputation: 150070

I don't know about DateJS, but if you've found that it is assuming MMddyyyy where you want ddMMyyyy then you could do a quick replace on your string to switch it to MMddyyyy before parsing:

Date.parse( '01062012'.replace(/^(\d\d)(\d\d)(\d\d\d\d)$/,"$2$1$3") );

Or do a similar replace to insert hyphens and make it dd-MM-yyyy:

Date.parse( '01062012'.replace(/^(\d\d)(\d\d)(\d\d\d\d)$/,"$1-$2-$3") );

Either way a string that already had hyphens in it would be left unchanged and thus be parsed as per your first (successful) test case.

Upvotes: 2

Related Questions