I am trying to parse a date of the format January 1, 1900
or February 1, 1900
etc for all of the months.. and then separate the month, day, and year into their own objects.
I have tried using an out-of-the-box regular expression for this but:
- This particular regex seems overplicated and like it could break easily
- There has to be an easier regular expression to use knowing that the format will not change (and we will validate the date on the backend)
I don't want to use the DateJS library since it seems like a lot of code to include just to parse one date, so is there an easier way to write a regular expression for this? Is there a different route other than doing regular expressions or DateJS?
For whatever reason, the regular expression does not work for February and as you can see it returns quite a few objects in an array, whereas it would obviously be easier if it just returned 3 objects (month, day, year). Here is the current function I wrote with the regular expression I am using...:
function convertDate(dateString) {
// must be in the format MMMMMMM DD, YYYY OR MMM DD, YYYY
// examples: January 1, 2000 or Jan 1, 2000 (notice no period for abbreviating January into Jan)
var dateRegex = new RegExp('^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sept|Nov|Dec)(ember)?)\\ (0?[1-9]|([12]\\d)|30))|(Feb(ruary)?\\ (0?[1-9]|1\\d|2[0-8]|(29(?=,\\ ((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\\,\\ ((1[6-9]|[2-9]\\d)\\d{2}))');
var fullDate = dateString.match(dateRegex);
console.log(fullDate);
if (fullDate) {
var month = fullDate[12];
var day = fullDate[24];
var year = fullDate[35];
if (month == 'January' | month == 'Jan') { integerMonth = 1; }
else if (month == 'February' | month == 'Feb') { integerMonth = 2; }
else if (month == 'March' | month == 'Mar') { integerMonth = 3; }
else if (month == 'April' | month == 'Apr') { integerMonth = 4; }
else if (month == 'May') { integerMonth = 5; }
else if (month == 'June' | month == 'Jun') { integerMonth = 6; }
else if (month == 'July' | month == 'Jul') { integerMonth = 7; }
else if (month == 'August' | month == 'Aug') { integerMonth = 8; }
else if (month == 'September' | month == 'Sep') { integerMonth = 9; }
else if (month == 'October' | month == 'Oct') { integerMonth = 10; }
else if (month == 'November' | month == 'Nov') { integerMonth = 11; }
else if (month == 'December' | month == 'Dec') { integerMonth = 12; }
return {month : integerMonth, day : day, year : year}
} else {
return false;
}
}
I am trying to parse a date of the format January 1, 1900
or February 1, 1900
etc for all of the months.. and then separate the month, day, and year into their own objects.
I have tried using an out-of-the-box regular expression for this but:
- This particular regex seems overplicated and like it could break easily
- There has to be an easier regular expression to use knowing that the format will not change (and we will validate the date on the backend)
I don't want to use the DateJS library since it seems like a lot of code to include just to parse one date, so is there an easier way to write a regular expression for this? Is there a different route other than doing regular expressions or DateJS?
For whatever reason, the regular expression does not work for February and as you can see it returns quite a few objects in an array, whereas it would obviously be easier if it just returned 3 objects (month, day, year). Here is the current function I wrote with the regular expression I am using...:
function convertDate(dateString) {
// must be in the format MMMMMMM DD, YYYY OR MMM DD, YYYY
// examples: January 1, 2000 or Jan 1, 2000 (notice no period for abbreviating January into Jan)
var dateRegex = new RegExp('^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sept|Nov|Dec)(ember)?)\\ (0?[1-9]|([12]\\d)|30))|(Feb(ruary)?\\ (0?[1-9]|1\\d|2[0-8]|(29(?=,\\ ((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\\,\\ ((1[6-9]|[2-9]\\d)\\d{2}))');
var fullDate = dateString.match(dateRegex);
console.log(fullDate);
if (fullDate) {
var month = fullDate[12];
var day = fullDate[24];
var year = fullDate[35];
if (month == 'January' | month == 'Jan') { integerMonth = 1; }
else if (month == 'February' | month == 'Feb') { integerMonth = 2; }
else if (month == 'March' | month == 'Mar') { integerMonth = 3; }
else if (month == 'April' | month == 'Apr') { integerMonth = 4; }
else if (month == 'May') { integerMonth = 5; }
else if (month == 'June' | month == 'Jun') { integerMonth = 6; }
else if (month == 'July' | month == 'Jul') { integerMonth = 7; }
else if (month == 'August' | month == 'Aug') { integerMonth = 8; }
else if (month == 'September' | month == 'Sep') { integerMonth = 9; }
else if (month == 'October' | month == 'Oct') { integerMonth = 10; }
else if (month == 'November' | month == 'Nov') { integerMonth = 11; }
else if (month == 'December' | month == 'Dec') { integerMonth = 12; }
return {month : integerMonth, day : day, year : year}
} else {
return false;
}
}
Share
Improve this question
asked Feb 16, 2011 at 16:54
iwasrobbediwasrobbed
46.8k21 gold badges152 silver badges195 bronze badges
2 Answers
Reset to default 5The Javascript Date object can be initialized with a string, and it will parse the format you are using into the correct date:
var d = new Date("January 1, 2000");
if (!isNaN(d.getMonth()) { // check for invalid date
return {month : d.getMonth()+1, day : d.getDate(), year : d.getFullYear()};
} else {
return false;
}
As you can see, this function is quite a bit simpler, and should be supported in all modern browsers.
This will work but is not going to be specific to months and years. It just requires 3-9 letters, one or two numbers, one ma and 4 numbers.
/^[a-z]{3,9} [0-9]{1,2}, [0-9]{4}$/i