Regular expression for matching time in military (24 hour) format
Asked Answered
D

15

48

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
  • 5672
Drayage answered 29/9, 2009 at 20:12 Comment(0)
S
134

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
Spavined answered 29/9, 2009 at 20:18 Comment(5)
24:00 doesn't exist but is matched. Change [0-4] to [0-3].Susuable
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 :)Lamrert
strager: 24:00 is perfectly valid, referring to the exact end of a day (and technically being the next day at 0:00). See en.wikipedia.org/wiki/24_hour_time#Midnight_00:00_and_24:00Smutty
@strager—nor do 12pm and 12am, but people keep usint them… ;-)Nonconformity
Human friendly equivalent would be: ^([0-1][0-9]|2[0-3]):?([0-5][0-9])$Wernher
I
12
/(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/

:)

Incontestable answered 29/9, 2009 at 20:16 Comment(3)
You didn't make the colon optional.Societal
this answer is so much better than the accepted one. The accepted one ins unreadable without commentsHorsa
That regex simplifies to: /([01]\d|2[0-3]):?[0-5]\d/.Cargo
K
8

Here is a better solution than the top one above for military plus a civilian solution.

Military

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

I believe the or in the highest rated response is not properly parsing the subsets before and after without the extra set of parenthesis to group them. Also, I'm not certain that the \d is just 0-9 in all iterations. It technically includes the special [[:digit:]] although I've never dealt with that being an issue before. Any how, this should provide every thing including the crossover 2400/24:00

Civilian

^([0-9]|([1][0-2])):[0-5][0-9][[:space:]]?([ap][m]?|[AP][M]?)

This is a nice Civilian version that allows for the full range formatted like 12:30PM, 12:30P, 12:30pm, 12:30p, 12:30 PM, 12:30 P, 12:30 pm, or 12:30 p but requires the morning or post meridian characters to be the same case if both are included (no Am or pM).

I use both of these in a bit of JavaScript to validate time strings.

Kail answered 8/10, 2014 at 15:17 Comment(4)
Thanks, I like this one. I did add the $ at the end of it though. Also, I made the 0 optional at the beginning (i.e. 01:25 could be 1:25). Hopefully didn't mess anything up along the way. ^(((([0-1]?[0-9])|(2[0-3])):?[0-5][0-9])|(24:?00))$Marrakech
The civilian one doesn't seem to work. If you throw it into regexr.com and try 12:30p, it returns no matches.Eardrop
Works fine in regex101.com. Perhaps you misryped it instead of copy/paste? Regexr.com doesn't work on mobile devices or I would check.Kail
There is no limit on the end of the regex, it will allow other characters to be entered at the end and still match, eg 13:4502938Chlorella
E
2

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.

Embroidery answered 29/9, 2009 at 20:19 Comment(0)
B
0

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!

Bellwort answered 29/9, 2009 at 20:21 Comment(1)
Yeah, he could just generate all possible times to an array (should be less than 16k), and then it is just a comparison =)Incontestable
C
0

This is the one I've just come up with:

(^((2[0-4])|([01]?[0-9])):[0-5][0-9]$)|(^((1[0-2])|(0?[1-9])(:[0-5][0-9])?)[pa]m$)

Accepts:

2pm
4:30am
07:05am
18:45
6:19
00:55

does not accept 00:05am - I am not sure if there is such time as 0am

If you feel that : is optional for 24h time format (military) - just add a question mark after it

Cordate answered 12/7, 2012 at 3:16 Comment(0)
C
0

I know this is an old question but here's a regex I came up with which seems to work.

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

You can edit it on this regex site

Edit I just realised that this answer ended up exactly the same as the accepted answer but I will leave it here at least for the value of the 'do it yourself' link

Chlorella answered 10/11, 2016 at 6:37 Comment(0)
A
0

This is perfect:

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

Note: 12 Hr Clock Only

For Times like:

0:01- 12:59
00:01 - 12:59
Amok answered 11/12, 2016 at 23:43 Comment(1)
Sorry: This is the perfect one: (([0-9][0-2]?)|([0][0-9])):[0-5][0-9]$Amok
W
0

A human friendly version:

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

Wernher answered 29/7, 2021 at 5:41 Comment(0)
C
0

I've done this slightly differently to avoid the possibility of a single zero leading the time, like 0:45 vs 00:45. From what I can see, the more commonly used format allows for this technically incorrect format. Mine also prevents pattern matches in trailing characters, as others have done.

\b^(0?[1-9]|[0-1][0-9]|2[0-3]):([0-5][0-9])(:[0-5][0-9])?$
Chesna answered 25/8, 2021 at 5:18 Comment(0)
I
0

This regex will also pass for when leading zero is not there. Example: 1:11:11

(0?[0-9]|[0-1][0-9]|2[0-3]):([0-5]\d):([0-5]\d))
Indebted answered 26/10, 2021 at 19:25 Comment(0)
S
0

Try this i think this is the best regex

data-inputmask-regex="^([0-1][0-9]|[2][0-3]):[0-5][0-9]$"
Serge answered 14/11, 2022 at 10:30 Comment(0)
S
-1
/^(?:[01]\d|2[0-3]):?[0-5]\d$/
Societal answered 29/9, 2009 at 20:15 Comment(0)
E
-1

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.

Erbium answered 29/9, 2009 at 20:17 Comment(3)
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.Erbium
Oh, there are plenty of ways to mess up your solution, too. Especially if you're trying to type fast like we were.Societal
Plenty of WAYS to mess it up? Sure. Easy to mess up? No. Easy to spot a mistake? Yes. Regex? No.Erbium
C
-1

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.

Cargo answered 29/9, 2009 at 20:22 Comment(1)
2380 is invalid. You have to compare both sides as I suggested.Erbium

© 2022 - 2024 — McMap. All rights reserved.