I would invert month and day positions first do get the same format for all dates :
function splitDate(input) {
return input.replace(
/^(\w+)-(\d+)/, '$2-$1'
).split('-');
}
var parts = splitDate('Feb-12-2012'); // ["12", "Feb", "2012"]
var parts = splitDate('12-Feb-2012'); // ["12", "Feb", "2012"]
var day = parts[0];
var month = parts[1];
var year = parts[2];
/^(\w+)-(\d+)/
matches only "Mmm-dd-yyyy" :
^ beginning of the input
(\w+) a word character, one or more times ($1)
- a dash
(\d+) a digit, one or more times ($2)
To go further
Now that you know how to split the input, I'd like to go further by turning the result into a Date object. Firstly, let's open the Chrome's console to quick check if the input is parseable as is :
new Date('12-Feb-2012') // Sun Feb 12 2012...
new Date('Feb-12-2012') // Sun Feb 12 2012...
Apparently, Chrome can get this job done properly. This is great, but other implementations do not necessarily behave the same way, you should better rely on the specifications. Luckily, someone has already checked them for you : undocumented supported Date.parse format?
To summarize roughly, the ability to parse your own formats is likely to vary across implementations. There is only one reliable format, namely YYYY-MM-DDTHH:mm:ss.sssZ
, where every letter - except "T" and "Z" - stands for a digit.
To be precise, MM
is expected to be a number. If you want to be sure that your input will be parsed properly, you have to find a way to turn the month part into a number. Let's try something :
var months = {
Jan: '01', Feb: '02', Mar: '03', Apr: '04', May: '05', Jun: '06',
Jul: '07', Aug: '08', Sep: '09', Oct: '10', Nov: '11', Dec: '12'
};
var parts = splitDate('Feb-12-2012'); // ["12", "Feb", "2012"]
parts[1] = months[parts[1]]; // parts -> ["12", "02", "2012"]
Not so bad, and the job is almost done. Indeed, as mentionned in the specs, the parser accepts date only formats like YYYY-MM-DD
, which is very easy to achieve :
parts = parts.reverse(); // ["2012", "02", "12"]
parts = parts.join('-'); // "2012-02-12"
Let's see what the console says :
new Date(parts) // Sun Feb 12 2012...
Done!
To close the case
Alternatively, you could do this :
var parts = splitDate('Feb-12-2012'); // ["12", "Feb", "2012"]
parts[1] = months[parts[1]]; // parts -> ["12", "02", "2012"]
var date = new Date(parts[2], parts[1] - 1, parts[0]);
You could go even further by hiding the process into a function :
function parseDate(input) {
var map = {
Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5,
Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov: 10, Dec: 11
};
return (parseDate = function (input) {
input = input.replace(/^(\w+)-(\d+)/, '$2-$1').split('-');
return new Date(input[2], map[input[1]], input[0]);
})(input);
};
Usage examples :
var date = parseDate('12-Feb-2012'); // Sun Feb 12 2012...
var date = parseDate('Feb-12-2012'); // Sun Feb 12 2012...
Feel free to ask for details.