views:

397

answers:

7

I would like a javascript regular expression that will match time using the 24 hour clock, where the time is given with or without the colon.

For example, I would like to match time in the following formats:

"0800", "23:45", "2345"

but that would not match invalid times such as

"34:68" or "5672"

A: 
/^(?:[01]\d|2[0-3]):?[0-5]\d$/
Jeremy Stein
This will match 29:00
Greg
Fixed. Thanks, Greg.
Jeremy Stein
A: 
/(00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23):?(0|1|2|3|4|5)\d/

:)

Zed
You didn't make the colon optional.
Jeremy Stein
Thank. I was typing number too fast so I forgot it :)
Zed
A: 

I don't think regex is the right solution for this problem. Sure, it COULD be done, but it just seems wrong.

Make sure your string is four characters long, or 5 characters with a colon in the middle. Then, parse each side and make sure that the left side is less than 24 and the right hand is less than 60.

The regex solution is just so much more complicated.

Stefan Kendall
Why isn't regexp a good solution?
strager
Have you not read the other posts? There were numerous attempts, and barely ANYONE got the solution correct (or even understood the problem entirely). My solution is pretty hard to mess up in any language or implementation.
Stefan Kendall
Oh, there are plenty of ways to mess up your solution, too. Especially if you're trying to type fast like we were.
Jeremy Stein
Plenty of WAYS to mess it up? Sure. Easy to mess up? No. Easy to spot a mistake? Yes. Regex? No.
Stefan Kendall
+9  A: 

This should do it:

^([01]\d|2[0-3]):?([0-5]\d)$

The expression reads:

^        Start of string (anchor)
(        begin capturing group
  [01]   a "0" or "1"
  \d     any digit
 |       or
  2[0-3] "2" followed by a character between 0 and 3 inclusive
)        end capturing group
:?       optional colon
(        start capturing
  [0-5]  character between 0 and 5
  \d     digit
)        end group
$        end of string anchor
Greg
24:00 doesn't exist but is matched. Change `[0-4]` to `[0-3]`.
strager
Oops.. brain-wrong
Greg
or in the form:^(([0-9])|([0-1][0-9])|([2][0-3])):?([0-5][0-9])$if you do not like the \d stuff :)
Mark Schultheiss
ooops, that allows 1:23 so the leading 0 is ommitted sorry..
Mark Schultheiss
strager: 24:00 is perfectly valid, referring to the exact *end* of a day (and technically being the next day at 0:00). See http://en.wikipedia.org/wiki/24_hour_time#Midnight_00:00_and_24:00
Joey
+2  A: 

To keep the colon optional and allow all valid times:

([01]\d|2[0-3]):?[0-5]\d

Note that this assumes midnight will always be 0000 and never 2400.

DocMax
A: 

Here's a blog post, looking for the same thing and a bunch of potential answers -- most of which don't work, but there is good discussion as to why each fails.

Of course, explicitly long and accurate is always a possibility!

Michael Paulukonis
Yeah, he could just generate all possible times to an array (should be less than 16k), and then it is just a comparison =)
Zed
A: 

Remove the ':' if the string has one, then if the string is of the form "DDDD", convert it into an int and compare it to 2400.

Loadmaster
2380 is invalid. You have to compare both sides as I suggested.
Stefan Kendall
Ack, you're right.
Loadmaster