Ste*_*tew 4 python validation datetime iso8601 arrow-python
我想编写一个函数,该函数接受一个字符串并返回True一个有效的ISO-8601日期时间(精确到微秒,包括时区偏移量),False否则返回。
我发现其他 问题提供了不同的解析日期时间字符串的方式,但是我只想返回TrueISO-8601格式。除非对不匹配ISO-8601的格式抛出错误,否则解析不会对我有帮助。
(我在代码的其他地方使用了漂亮的箭头库。arrow欢迎使用该解决方案。)
编辑:似乎在通用Python日期时间包中不存在“此字符串是否为有效的ISO 8601日期时间”的常规解决方案。
因此,为了使这个问题更窄,更具体和可回答,我将选择一种格式字符串,该格式字符串将验证以下格式的日期时间字符串:
'2016-12-13T21:20:37.593194+00:00'
Run Code Online (Sandbox Code Playgroud)
目前,我正在使用:
format_string = '%Y-%m-%dT%H:%M:%S.%f%z'
datetime.datetime.strptime(my_timestamp, format_string)
Run Code Online (Sandbox Code Playgroud)
这给出:
ValueError: time data '2016-12-13T21:20:37.593194+00:00' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'
Run Code Online (Sandbox Code Playgroud)
问题似乎在于UTC偏移(+00:00)中的冒号。如果我使用不带冒号的偏移量(例如'2016-12-13T21:20:37.593194+0000'),则可以按预期正确解析。显然,这是因为datetime的%z令牌不尊重带有冒号的UTC偏移量格式,只有不包含冒号的格式,即使这两个规范均有效。
最近版本的 Python(从 3.7 开始)fromisoformat()在datetime标准库中有一个函数。请参阅:https : //docs.python.org/3.7/library/datetime.html
所以这将解决问题:
from datetime import datetime
def datetime_valid(dt_str):
try:
datetime.fromisoformat(dt_str)
except:
return False
return True
Run Code Online (Sandbox Code Playgroud)
更新:
我了解到 Python 无法将“Z”后缀识别为有效。因为我想在我的 API 中支持这一点,所以我现在使用:
from datetime import datetime
def datetime_valid(dt_str):
try:
datetime.fromisoformat(dt_str)
except:
try:
datetime.fromisoformat(dt_str.replace('Z', '+00:00'))
except:
return False
return True
return True
Run Code Online (Sandbox Code Playgroud)
小智 7
以ISO8601格式提供许多变体来验证日期和时间(例如2008-08-30T01:45:36或2008-08-30T01:45:36.123Z)。XML模式dateTime类型的正则表达式为:
>>> regex = r'^(-?(?:[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]+)?(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])?$'
Run Code Online (Sandbox Code Playgroud)
因此,为了验证您可以执行以下操作:
>>> import re
>>> match_iso8601 = re.compile(regex).match
>>> def validate_iso8601(str_val):
... try:
... if match_iso8601( str_val ) is not None:
... return True
... except:
... pass
... return False
Run Code Online (Sandbox Code Playgroud)
一些例子:
>>> validate_iso8601('2017-01-01')
False
>>> validate_iso8601('2008-08-30T01:45:36.123Z')
True
>>> validate_iso8601('2016-12-13T21:20:37.593194+00:00')
True
Run Code Online (Sandbox Code Playgroud)
考虑到您对问题施加的约束,您可以使用正则表达式轻松解决它。
>>> import re
>>> re.match(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{6}[+-]\d\d:\d\d$', '2016-12-13T21:20:37.593194+00:00')
<_sre.SRE_Match object; span=(0, 32), match='2016-12-13T21:20:37.593194+00:00'>
Run Code Online (Sandbox Code Playgroud)
如果您需要通过ISO 8601 的所有变体,这将是一个更加复杂的正则表达式,但仍然可以完成。如果您还需要验证数字范围,例如验证小时是否在 0 到 23 之间,您可以将括号放入正则表达式中以创建匹配组,然后验证每个组。
| 归档时间: |
|
| 查看次数: |
7011 次 |
| 最近记录: |