Javascript javascript正则表达式iso日期时间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3143070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javascript regex iso datetime
提问by Scott Klarenbach
does anyone have a good regex pattern for matching iso datetimes?
有没有人有一个很好的正则表达式模式来匹配 iso 日期时间?
ie: 2010-06-15T00:00:00
即:2010-06-15T00:00:00
回答by Brock Adams
For the strict, full datetime, including milliseconds, per the W3C's take on the spec.:
对于严格的、完整的日期时间,包括毫秒,根据W3C 对规范的看法。:
//-- Complete precision:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/
//-- No milliseconds:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z)/
//-- No Seconds:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z)/
//-- Putting it all together:
/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/
.
Additional variations allowed by the actual ISO 8601:2004(E) doc:
.
实际ISO 8601:2004(E) 文档允许的其他变化:
/********************************************
** No time-zone varients:
*/
//-- Complete precision:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+/
//-- No milliseconds:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d/
//-- No Seconds:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d/
//-- Putting it all together:
/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d)/
WARNING: This all gets messy fast, and it stillallows certain nonsense such as a 14th month. Additionally, ISO 8601:2004(E) allows a several other variants.
警告:这一切很快就会变得混乱,它仍然允许某些废话,例如第 14 个月。此外,ISO 8601:2004(E) 允许多种其他变体。
."2010-06-15T00:00:00" isn't legal, because it doesn't have the time-zone designation.
. "2010-06-15T00:00:00" 不合法,因为它没有时区指定。
回答by Sergey P. aka azure
For matching just ISO date, like 2017-09-22, you can use this regexp:
为了匹配 ISO 日期,比如 2017-09-22,你可以使用这个正则表达式:
^\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
它将匹配任何数字年份、由 00-12 范围内的两位数字指定的任何月份以及由 00-31 范围内的两位数字指定的任何日期
回答by dbeach
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?)?)?)?/
/[+-]?\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
你可以在这里找到我建议的答案的测试:http: //regexr.com/3e0lh
回答by Rbjz
Here is a regular expression to check ISO 8601 dateformat 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
这是检查 ISO 8601日期格式的正则表达式,包括闰年和短长月。要运行它,您需要“忽略空白”。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.
ISO 8601 还有更多内容 - 这个正则表达式只关心日期,但您可以轻松扩展它以支持时间验证,这并不那么棘手。
Update: This works now with javascript (without lookbehinds)
更新:这现在适用于 javascript(没有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)
(?:
(?:0[1-9]|[12][0-9]|3[01])
)?
|
(?:04|06|09|11)
(?:
(?:0[1-9]|[12][0-9]|30)
)?
|
02
(?:
(?:0[1-9]|[12][0-9])
)?
|
W(?:0[1-9]|[1-4][0-9]|5[0-3])
(?:
[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)
(?:
(?:0[1-9]|[12][0-9]|3[01])
)?
|
(?:04|06|09|11)
(?:
(?:0[1-9]|[12][0-9]|30)
)?
|
(?:02)
(?:
(?:0[1-9]|1[0-9]|2[0-8])
)?
|
W(?:0[1-9]|[1-4][0-9]|5[0-3])
(?:
[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/):
为了满足时间,在混合物中添加类似的东西(来自:http: //underground.infovark.com/2008/07/22/iso-date-validation-regex/):
([T\s](([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)?(([0-5]\d))?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?
回答by Scott S. McCoy
The ISO 8601specification allows a wide variety of date formats. There's a mediocre explanation as to how to do it here. There is a fairly minor discrepancy between how Javascript's date input formatting and the ISO formatting for simple dates which do not specify timezones, and it can be easily mitigated using a string substitution. Fully supporting the ISO-8601 specification is non-trivial.
在ISO 8601规范允许各种各样的日期格式。这里有一个关于如何做到这一点的平庸解释。Javascript 的日期输入格式与不指定时区的简单日期的 ISO 格式之间存在相当小的差异,并且可以使用字符串替换轻松缓解。完全支持 ISO-8601 规范并非易事。
Here is a reference example which I do not guarantee to be complete, although it parses the non-duration dates from the aforementioned Wikipedia page.
这是一个参考示例,我不保证它是完整的,尽管它解析了上述 Wikipedia 页面中的非持续时间。
Below is an example, and you can also see it's output on ideone. Unfortunately, it does not work to specification as it does not properly implement weeks. The definition of the week number 01 in ISO-8601 is non-trivial and requires some browsing the calendar to determine where week one begins, and what exactly it means in terms of the number of days in the specified year. This can probably be fairly easily corrected (I'm just tired of playing with it).
下面是一个示例,您还可以在 ideone 上看到它的输出。不幸的是,它不符合规范,因为它没有正确实施几周。ISO-8601 中周数 01 的定义非常重要,需要浏览日历才能确定第一周从哪里开始,以及它在指定年份的天数方面的确切含义。这可能很容易纠正(我只是厌倦了玩它)。
function parseISODate (input) {
var iso = /^(\d{4})(?:-?W(\d+)(?:-?(\d+)D?)?|(?:-(\d+))?-(\d+))(?:[T ](\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?)?(?:Z(-?\d*))?$/;
var parts = input.match(iso);
if (parts == null) {
throw new Error("Invalid Date");
}
var year = Number(parts[1]);
if (typeof parts[2] != "undefined") {
/* Convert weeks to days, months 0 */
var weeks = Number(parts[2]) - 1;
var days = Number(parts[3]);
if (typeof days == "undefined") {
days = 0;
}
days += weeks * 7;
var months = 0;
}
else {
if (typeof parts[4] != "undefined") {
var months = Number(parts[4]) - 1;
}
else {
/* it's an ordinal date... */
var months = 0;
}
var days = Number(parts[5]);
}
if (typeof parts[6] != "undefined" &&
typeof parts[7] != "undefined")
{
var hours = Number(parts[6]);
var minutes = Number(parts[7]);
if (typeof parts[8] != "undefined") {
var seconds = Number(parts[8]);
if (typeof parts[9] != "undefined") {
var fractional = Number(parts[9]);
var milliseconds = fractional / 100;
}
else {
var milliseconds = 0
}
}
else {
var seconds = 0;
var milliseconds = 0;
}
}
else {
var hours = 0;
var minutes = 0;
var seconds = 0;
var fractional = 0;
var milliseconds = 0;
}
if (typeof parts[10] != "undefined") {
/* Timezone adjustment, offset the minutes appropriately */
var localzone = -(new Date().getTimezoneOffset());
var timezone = parts[10] * 60;
minutes = Number(minutes) + (timezone - localzone);
}
return new Date(year, months, days, hours, minutes, seconds, milliseconds);
}
print(parseISODate("2010-06-29T15:33:00Z-7"))
print(parseISODate("2010-06-29 06:14Z"))
print(parseISODate("2010-06-29T06:14Z"))
print(parseISODate("2010-06-29T06:14:30.2034Z"))
print(parseISODate("2010-W26-2"))
print(parseISODate("2010-180"))
回答by Plix
with 02/29 validation from the year 1900 to 2999
从 1900 年到 2999 年的 02/29 验证
(((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
回答by ferpel
I have made this regex and solves the validation for dates as they come out of Javascript's .toISOString()method.
我已经制作了这个正则表达式并解决了日期验证,因为它们来自 Javascript 的.toISOString()方法。
^[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$
^[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:
考虑:
- Proper symbols ('-', 'T', ':', '.', 'Z') in proper places.
- Consistency with months of 29, 30 or 31 days.
- Hours from 00 to 23.
- Minutes and seconds from 00 to 59.
- Milliseconds from 000 to 999.
- 在适当的位置使用适当的符号('-'、'T'、':'、'.'、'Z')。
- 与 29、30 或 31 天的月份保持一致。
- 小时从 00 到 23。
- 从 00 到 59 的分和秒。
- 从 000 到 999 的毫秒数。
Not contemplated:
未考虑:
- Leap years.
- 闰年。
Example date:2019-11-15T13:34:22.178Z
示例日期: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");
直接在 Chrome 控制台中运行的示例:/^[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):
正则表达式流程图(Regexper):
回答by jiggy
Not sure if it's relevant to the underlying problem you are trying to solve, but you can pass an ISO date string as a constructor arg to Date() and get an object out of it. The constructor is actually very flexible in terms of coercing a string into a Date.
不确定它是否与您尝试解决的潜在问题相关,但是您可以将 ISO 日期字符串作为构造函数 arg 传递给 Date() 并从中获取一个对象。构造函数实际上在将字符串强制转换为日期方面非常灵活。

