Reputation: 5968
I'm trying to find a best way to test if a string fits a current criteria. Basically, I have a date coming in as such:
1/17/2013 12:00 AM
The month and day fields can be one or two digits, while the year is always four. The hour can be one or two digits. The minute field is always two digits For example, this is also applicable:
10/1/2013 1:00 AM
Right now, I have this regex, but it doesn't seem to be working:
/^(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\/(20[1-9][2-9]) (0[1-9]|1[0-2]):([0-5][0-9]) (am|pm)$/
I am using it as such:
$('input[name=targetMe]').each( function() {
alert('start')
if(/^(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\/(20[1-9][2-9]) (0[1-9]|1[0-2]):([0-5][0-9]) (AM|PM)$/.test($(this).val())) {
alert('passes')
} else {
alert('dont')
}
});
Is there something wrong with my current regex, or should I be using it in another way, or is there a better solution out there than this?
Upvotes: 1
Views: 299
Reputation: 19457
You can try Date.Parse
to try to determine if the string is a valid date. However, as the method is implemenation dependant, you should also read the notes on this - javascripts and dates what mess.
To answer the orignal question, a simple regex as below should suffice.
^([1-9]|1[0-2]?)/([1-9]|[1-2][0-9]|3[0-1])/(19|20)[0-9][0-9] +(0?[0-9]|1[0-2]?):[0-5][0-9] +(a|p)m$
** Corrected to filter some incorrect values - Digits != Time **
The above will validate a date if the days and months are 1 or 2 digits, year is four with the starting digits begining 20
, hours are 1 or 2 digits and minutes are 2 digits. The date and time are separated by two spaces.
I have used the RegExp object as the direct input seems to have an issue with /
being interrupted as end of expression. Also, I have added "i" flag for case insensitive search for am/pm. Either escape it or change to use the object.
var regex = "^([1-9]|1[0-2]?)/([1-9]|[1-2][0-9]|3[0-1])/(19|20)[0-9][0-9] +(0?[0-9]|1[0-2]?):[0-5][0-9] +(a|p)m$";
var val = "1/17/2013 12:00 AM";
if(new RegExp(regex, "i").test(val)){
alert("Success");
} else {
alert("Fail");
}
Upvotes: 1
Reputation: 5968
Okay, this is the final solution I found that combines all the great input I received here!
$('input[name=targetMe]').each( function() {
alert('start')
if(/^([1-9]|1[0-2])\/([1-9]|[1-2][0-9]|3[0-1])\/(19[0-9][0-9]|20[0-9][2-9]) (0[1-9]|1[0-2]):([0-5][0-9]) (am|pm|AM|PM)$/.test($(this).val())) {
alert('passes')
} else {
alert('dont')
}
});
This will accept anything in the 1900s or 2000s, and single and double digits for days and months.
Upvotes: 1
Reputation: 9219
Try:
/^(0?[1-9]|1[0-2])\/(0?[1-9]|[12]\d|3[01])\/(20[1-9]\d) (0?[1-9]|1[0-2]):([0-5]\d) ([AP]M)$/
Note that this matches any year from (and including) 2010 to 2099. Your regex implies you only want years from 2012-2099, in which case, use something like 20(1[2-9]|[2-9]\d)
Upvotes: 1
Reputation: 45
I believe you can use the parse method in Javascript:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/parse
so it will be something like:
$('input[name=targetMe]').each( function() {
alert('start')
if(Date.parse($(this).val())) {
alert('passes')
} else {
alert('dont')
}
});
Upvotes: 1