views:

539

answers:

10

How could you match 12 hour time in a regex-- in other words match 12:30 but not 14:74? Thanks!

+13  A: 

([1-9]|1[012]):[0-5][0-9] should work

Keith
This will match 0:59.
Brian
I corrected it.
Brian
Note that this one matches "3:00" in "13:00".
Cide
Yep, but it looks like someone corrected it for me =)
Keith
What's wrong with 0:59? That's one minute to 1am...
Boldewyn
The above still fails for "13:00" (by matching "3:00"), and doesn't match "00:00".
Cide
([1-9]|1[012]):[0-5][0-9] -- just for kicks.
tvanfosson
@tvanfosson My thoughts exactly ;)
ojrac
@Cide: True, but Adrian did not define a delimitter. We could, of course, prepend it with [^\d].
Brian
http://en.wikipedia.org/wiki/24-hour_clock#Midnight_00:00_and_24:00
CptSkippy
@Brian I'd vote for \b or a lookbehind for (?<!\d) to avoid capturing anything but the time. (Semantics aside, I totally agree.) And 00:00 isn't a 12-hour time; that's written 12:00.
ojrac
This matches parts of times over 12:59 (e.g. on 13:23 it matches 3:23)
CptSkippy
A: 

Like this: ((?:1[0-2]|0\d)\:(?:[0-5]\d)) if you want leading 0 for the hour, ((?:1[0-2]|\d)\:(?:[0-5]\d)) if you don't and ((?:1[0-2]|0?\d)\:(?:[0-5]\d)) if you don't care.

streetpc
That would mandate a leading 0 wouldn't it? e.g. would match 05:02 but not 5:02?
Joe
fixed that: you want, you don't or you don't care :)
streetpc
A: 

^(?:(?:1?(?:[0-2]))|[1-9]):[0-5][0-9]

SquareRootOf2
+13  A: 

This is an example of a problem where "hey I know, I'll use regular expressions!" is the wrong solution. You can use a regular expression to check that your input format is digit-digit-colon-digit-digit, then use programming logic to ensure that the values are within the range you expect. For example:

/(\d\d?):(\d\d)/

if ($1 >= 1 && $1 <= 12 && $2 < 60) {
    // result is valid 12-hour time
}

This is much easier to read and understand than some of the obfuscated regex examples you see in other answers here.

Greg Hewgill
A: 

I believe the above fail in at least one way, particularly regarding strings such as "13:00" (Keith's matches "3:00" in that case).

This one should handle that issue as well as the others brought up.

([01][0-2]|(?<!1)[0-9]):([0-5][0-9])
Cide
A: 
(0?\d|1[0-2]):([0-5]\d)

That will match everything from 0:00 up to 12:59. That's 13 hours, by the way. If you don't want to match 0:00 - 0:59, try this instead:

([1-9]|1[0-2]):([0-5]\d)
Daniel
A: 

You could use this one:

/((?:1[0-2])|(?:0?[0-9])):([0-5][0-9]) ?([ap]m)/

/1 => hour
/2 => minute
/3 => am/pm
PatrikAkerstrand
A: 

The following matches padded and non-padded hours in a 24hr clock (i.e. 00:00 - 23:59) between 00:00 and 12:59.

(?:(?<!\d)[0-9]|0[0-9]|1[0-2]):[0-5][0-9]

Matches:

  • 00:00
  • 00:58
  • 01:34
  • 1:34
  • 8:35
  • 12:23
  • 12:59

Nonmatches:

  • 13:00
  • 13:23
  • 14:45
  • 23:59
CptSkippy
+1  A: 

why regex? you can do this will simple integer check

$str = "12:74";
list($h , $m ) = explode(":",$str);
if ( ($h <=12 && $h >=0  ) && ($m <=59 && $m >=0) ) {
    print "Time Ok.";
}else{
    print "Time not ok";
}
ghostdog74
A: 

^(00|0[0-9]|1[012]):[0-5][0-9] ?((a|p)m|(A|P)M)$

^ - Match the beginning of the string.

(00|0[0-9]|1[012]) - any two-digit number up to 12. Require two digits.

: - Match a colon

[0-5][0-9] - Match any two-digit number from 00 to 59.

? - Match a space zero or one times.

((a|p)m|(A|P)M) Match am or pm, case insensitive.

$ - Match the end of the string.

Eli