Reputation: 2875
For example: 2015-01-17T18:23:02+00:00
Having some trouble with the regex as certain components of the string to be considered 'valid' are speculated and may not be required.
Also, the fact the string can be formatted as 2015-01-17T18:23:02Z
is throwing me slightly.
Upvotes: 39
Views: 45007
Reputation: 1
After struggling for a few hours I got this regex working:
^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30)))T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|[+-](\b(0[1-9]|1[0-7])\b:[0-5][0-9]|18:00))$
The only issue I've found so far has been that it allows for February 29th on non-leap years. Also, it only generates 4-digit years, but that is easier to change.
I've used this page to generate strings matching said regex and then tested them in this online Java compiler by trying
System.out.println(OffsetDateTime.parse(toParse[i]));
Upvotes: 0
Reputation: 156
if using regex is not mandatory, I think the best way to detect it in js is by doing this :
function isIso8601(value) {
return new Date(value).toJSON() === value;
}
isIso8601('2019-08-21T16:35:05.073Z'); // true
isIso8601('2013-99-99T04:13:00+00:00'); // false
Upvotes: 1
Reputation: 652
^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]{3})?(Z)?$
DateTime. Also covers optional Milliseconds.
Upvotes: 1
Reputation: 511
to match with date and timezones
2019-07-01T24:15:00+19:00
\d{4}-[01]{1}\d{1}-[0-3]{1}\d{1}T[0-2]{1}\d{1}:[0-6]{1}\d{1}:[0-6]{1}\d{1}[+|-][0-1][0-9]:[0-5][0-9]$
test it here https://regexr.com/4gmi2
Upvotes: 0
Reputation: 12215
Based on the previous answer, this regex handles the fraction of seconds.
^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d{1,9})?(?:Z|[+-][01]\d:[0-5]\d)$
Upvotes: 22
Reputation: 1263
If you just want to match time zones use this:
^[+|-][0-1][0-9]:[0-5][0-9]$
The max is + or - 19:59 which is sufficient
Upvotes: 1
Reputation: 685
In this link we see the different ISO 8601 formats based on different values we would like to include.
For the example in the question, 2015-01-17T18:23:02+00:00
, below regex should work.
[0-9]{4}-[0-9]{2}-[0-9]{2}T([0-9]{2}:){2}[0-9]{2}[+|-][0-9]{2}:[0-9]{2}
Here [+|-]
is for possible time zone offsets.
Upvotes: 4
Reputation: 4659
Based on an earlier answer of mine, you could do this and be pretty darn strict:
^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|[+-][01]\d:[0-5]\d)$
Slightly monstrous but it checks for valid dates including leap-year (Proleptic Gregorian), works for years 1000-9999, checks for invalid times like 25:30 or 21:94 and a maximum UTC offset of +/-19:59 (or a Z).
(right now more than +14:00 or -12:00 doesn't happen, but it might in the future).
For completion: This answer only supports a subset of the ISO8601 standard based on the examples OP gave. Which is the extended notation with seconds in the time section and minutes in the UTC offset. For brevity it does not support basic notation where dashes and colons are omitted, or the omitting of minutes in the UTC offset or the smallest unit. Nor is there support for ordinal dates (day-of-year) or year-week-dayofweek notations.
An extended version of the regex that supports basic notation, ordinal and the omitting of seconds / UTC-offset minutes lives here.
Upvotes: 79