does anyone have a good regex pattern for matching iso datetimes?
ie: 2010-06-15T00:00:00
I have made this regex and solves the validation for dates as they come out of Javascript's .toISOString()
method.
^[0-9]{4}-((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|(0[469]|11)-(0[1-9]|[12][0-9]|30)|(02)-(0[1-9]|[12][0-9]))T(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9]):(0[0-9]|[1-5][0-9])\.[0-9]{3}Z$
Contemplated:
Not contemplated:
Example date: 2019-11-15T13:34:22.178Z
Example to run directly in Chrome console: /^[0-9]{4}-((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|(0[469]|11)-(0[1-9]|[12][0-9]|30)|(02)-(0[1-9]|[12][0-9]))T(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9]):(0[0-9]|[1-5][0-9])\.[0-9]{3}Z$/.test("2019-11-15T13:34:22.178Z");
Regex flow diagram (Regexper):
Here is a regular expression to check ISO 8601 date format including leap years and short-long months. To run this, you'll need to "ignore white-space". A compacted version without white-space is on regexlib: http://regexlib.com/REDetails.aspx?regexp_id=3344
There's more to ISO 8601 - this regex only cares for dates, but you can easily extend it to support time validation which is not that tricky.
Update: This works now with javascript (without lookbehinds)
^(?:
(?=
[02468][048]00
|[13579][26]00
|[0-9][0-9]0[48]
|[0-9][0-9][2468][048]
|[0-9][0-9][13579][26]
)
\d{4}
(?:
(-|)
(?:
(?:
00[1-9]
|0[1-9][0-9]
|[1-2][0-9][0-9]
|3[0-5][0-9]
|36[0-6]
)
|
(?:01|03|05|07|08|10|12)
(?:
\1
(?:0[1-9]|[12][0-9]|3[01])
)?
|
(?:04|06|09|11)
(?:
\1
(?:0[1-9]|[12][0-9]|30)
)?
|
02
(?:
\1
(?:0[1-9]|[12][0-9])
)?
|
W(?:0[1-9]|[1-4][0-9]|5[0-3])
(?:
\1
[1-7]
)?
)
)?
)$
|
^(?:
(?!
[02468][048]00
|[13579][26]00
|[0-9][0-9]0[48]
|[0-9][0-9][2468][048]
|[0-9][0-9][13579][26]
)
\d{4}
(?:
(-|)
(?:
(?:
00[1-9]
|0[1-9][0-9]
|[1-2][0-9][0-9]
|3[0-5][0-9]
|36[0-5]
)
|
(?:01|03|05|07|08|10|12)
(?:
\2
(?:0[1-9]|[12][0-9]|3[01])
)?
|
(?:04|06|09|11)
(?:
\2
(?:0[1-9]|[12][0-9]|30)
)?
|
(?:02)
(?:
\2
(?:0[1-9]|1[0-9]|2[0-8])
)?
|
W(?:0[1-9]|[1-4][0-9]|5[0-3])
(?:
\2
[1-7]
)?
)
)?
)$
To cater for time, add something like this to the mixture (from: http://underground.infovark.com/2008/07/22/iso-date-validation-regex/ ):
([T\s](([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)?(\15([0-5]\d))?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?
Too much explanation for most of the answers here, here's a short variation of @Sergey answer addressing some weird scenarios (like 2020-00-00
), this RegExp
only cares about the yyyy-MM-dd
date:
// yyyy-MM-dd
^\d{4}-([0][1-9]|1[0-2])-([0-2][1-9]|[1-3]0|3[01])$
Also this one doesn't care about the number of days per month, like 2020-11-31
(because November has only 30 days).
My use-case was to convert a String
into a Date
(from an API
param) and I needed only to know that the input string didn't contained strange stuff, I do the next validation against an actual Date
object.
For matching just ISO date, like 2017-09-22, you can use this regexp:
^\d{4}-([0]\d|1[0-2])-([0-2]\d|3[01])$
It will match any numeric year, any month specified by two digits in range 00-12 and any date specified by two digits in range 00-31
with 02/29 validation from the year 1900 to 2999
(((2000|2400|2800|((19|2[0-9])(0[48]|[2468][048]|[13579][26])))-02-29)|(((19|2[0-9])[0-9]{2})-02-(0[1-9]|1[0-9]|2[0-8]))|(((19|2[0-9])[0-9]{2})-(0[13578]|10|12)-(0[1-9]|[12][0-9]|3[01]))|(((19|2[0-9])[0-9]{2})-(0[469]|11)-(0[1-9]|[12][0-9]|30)))T([01][0-9]|[2][0-3]):[0-5][0-9]:[0-5][0-9]\.[0-9]{3}Z
I reworked the top answer into something a bit more concise. Instead of writing out each of the three optional patterns, the elements are nested as optional statements.
/[+-]?\d{4}(-[01]\d(-[0-3]\d(T[0-2]\d:[0-5]\d:?([0-5]\d(\.\d+)?)?[+-][0-2]\d:[0-5]\dZ?)?)?)?/
I'm curious if there are downsides to this approach?
You can find tests for my suggested answer here: http://regexr.com/3e0lh