Python datetime.fromisoformat在tzinfo中需要冒号?

k2fxgqgv  于 2022-11-27  发布在  Python
关注(0)|答案(1)|浏览(106)

我正在解析另一个应用程序生成的isoformat格式的日期+时间值,如下所示:

"2022-07-31T01:51:05-0400"

注意:时区信息部分为“-0400”,不带冒号。
但我看不出要用datetime.fromisoformat来做这件事:

# This works fine (with a colon):

datetime.fromisoformat("2022-07-31T01:51:05-04:00")
datetime.datetime(2022, 7, 31, 1, 51, 05, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))

# But this does not (without a colon)

datetime.fromisoformat("2022-07-31T01:51:05-0400")
Traceback (most recent call last):
  File "/usr/lib/python3.10/code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
ValueError: Invalid isoformat string: '2000-10-20T01:02:03-0400'

有效的ISO 8601日期时间格式的定义明确包含类似“-0400”的字符串:
与UTC的时间偏移UTC偏移以与上面的“Z”相同的方式附加到时间上,格式为±[hh]:[mm],±[hh][mm]或±[hh]。
负的UTC偏移量描述了UTC±00:00以西的时区,其中民用时间晚于(或早于)UTC,因此时区标志符看起来像“−03:00”、"−0300”或“−03”。
正UTC偏移量描述了UTC±00:00或其以东的时区,其中民用时间与UTC相同或早于(或晚于)UTC,因此时区指示符将看起来像“+02:00”、"+0200”或“+02”。
来源:https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC
Python的日期时间文档说
classmethod datetime.fromisoformat(date_string)以任何有效的ISO 8601格式返回与date_string对应的日期时间,但以下情况除外:
时区偏移量可以是小数秒。
T分隔符可以替换为任何单个Unicode字符。
当前不支持顺序日期。
不支持小时和分钟小数。
非冒号形式不属于任何禁止的类别。
我知道我可以这样做:

datetime.strptime("2022-07-31T01:51:05-0400", '%Y-%m-%dT%H:%M:%S%z')

其中我明确指出了日期时间格式,但使用fromisoformat()的全部目的是为了不必查找格式代码并明确地拼写出来。
有没有什么方法可以做到这一点,同时仍然使用fromisoformat

ipakzgxi

ipakzgxi1#

您可以通过确保冒号位于字符串的UTC偏移量部分来解决此问题:

def fix_iso(s):
    pos = len("2022-07-31T01:51:05-0400") - 2 # take off end "00"
    if len(s) == pos:                 # missing minutes completely
        s += ":00"
    elif s[pos:pos+1] != ':':         # missing UTC offset colon
        s = f"{s[:pos]}:{s[pos:]}"
    return s

在输入到fromisoformat()之前,用这个处理字符串。这会处理丢失的冒号,也会处理偏移量中没有分钟的情况。
从OP和其他评论者的陈述来看,Python似乎夸大了标准合规性...

相关问题