如何解析ISO 8601格式的日期?

Ale*_*nko 583 python datetime iso8601 rfc3339 datetime-parsing

我需要将RFC 3339字符串解析"2008-09-03T20:56:35.450686Z"为Python的datetime类型.

strptime在Python标准库中找到了,但它不是很方便.

做这个的最好方式是什么?

Fli*_*imm 413

蟒蛇-dateutil包可以解析不仅RFC 3339日期时间字符串像在的问题,还包括其他ISO 8601不符合RFC 3339(日期和时间字符串,如没有UTC那些偏移,或那些代表只有约会).

>>> import dateutil.parser
>>> dateutil.parser.parse('2008-09-03T20:56:35.450686Z') # RFC 3339 format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686, tzinfo=tzutc())
>>> dateutil.parser.parse('2008-09-03T20:56:35.450686') # ISO 8601 extended format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
>>> dateutil.parser.parse('20080903T205635.450686') # ISO 8601 basic format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
>>> dateutil.parser.parse('20080903') # ISO 8601 basic format, date only
datetime.datetime(2008, 9, 3, 0, 0)
Run Code Online (Sandbox Code Playgroud)

请注意,这dateutil.parser是故意的hacky:它试图猜测格式并在不明确的情况下做出不可避免的假设(仅可手工定制).如果您需要解析未知格式的输入都还可以忍受偶尔的误读所以用它.(感谢ivan_pozdeev)

Pypi的名字python-dateutil不是dateutil(谢谢code3monk3y):

pip install python-dateutil
Run Code Online (Sandbox Code Playgroud)

如果你使用的是Python 3.7,看看这个答案datetime.datetime.fromisoformat.

  • 对于懒惰,它通过`python-dateutil`而不是`dateutil`安装,所以:`pip install python-dateutil`. (73认同)
  • 请注意,`dateutil.parser`是故意hacky:它试图猜测格式并在不明确的情况下做出不可避免的假设(仅可手工定制).因此,如果您需要解析未知格式的输入并且可以容忍偶尔的误读,那么只能使用它. (29认同)
  • 同意 例如,传递的“日期”为9999。这将返回与datetime(9999,当前月份,当前日期)相同的日期。我认为这不是有效日期。 (2认同)
  • @ivan_pozdeev 你会推荐什么包用于非猜测解析? (2认同)
  • @ivan_pozdeev 读取 iso8601 日期的模块有更新:https://dateutil.readthedocs.io/en/stable/parser.html#dateutil.parser.isoparse (2认同)

小智 158

注意在Python 2.6+和Py3K中,%f字符捕获微秒.

>>> datetime.datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")
Run Code Online (Sandbox Code Playgroud)

在这里看问题

  • 这个答案(以其当前的编辑形式)依赖于将特定的UTC偏移(即"Z",即+00:00)硬编码到格式字符串中.这是一个坏主意,因为它将无法使用不同的UTC偏移量解析任何日期时间并引发异常.请参阅[我的回答](http://stackoverflow.com/a/30696682/1709587),其中描述了如何使用`strptime`解析RFC 3339实际上是不可能的. (21认同)
  • 注意 - 如果使用Naive日期时间 - 我认为你根本没有TZ - Z可能不匹配任何东西. (4认同)
  • 在我的例子中 %f 捕获的是微秒而不是 Z, `datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f')` 所以这就成功了 (2认同)
  • Py3K 是指 Python 3000 吗?!? (2认同)
  • @Robino IIRC,"Python 3000"是现在称为Python 3的旧名称. (2认同)

Mar*_*ery 150

这里有几个答案 建议使用时区解析RFC 3339或ISO 8601日期时间,如问题中展示的那样: datetime.datetime.strptime

2008-09-03T20:56:35.450686Z
Run Code Online (Sandbox Code Playgroud)

这是一个坏主意.

假设您想要支持完整的RFC 3339格式,包括支持除零以外的UTC偏移,那么这些答案建议的代码不起作用.实际上,它无法工作,因为解析RFC 3339语法strptime是不可能的.Python的datetime模块使用的格式字符串无法描述RFC 3339语法.

问题是UTC偏移.在RFC 3339互联网日期/时间格式要求每个日期时间包括UTC偏移,并且这些偏移可以是Z(以下简称"祖鲁时间"),或在+HH:MM-HH:MM格式,如+05:00-10:30.

因此,这些都是有效的RFC 3339日期时间:

  • 2008-09-03T20:56:35.450686Z
  • 2008-09-03T20:56:35.450686+05:00
  • 2008-09-03T20:56:35.450686-10:30

唉,格式字符串使用strptime并且strftime没有与RFC 3339格式的UTC偏移相对应的指令.可以在https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior找到它们支持的指令的完整列表,列表中包含的唯一UTC偏移指令是%z:

%Z

UTC偏移量,格式为+ HHMM或-HHMM(如果对象是天真的,则为空字符串).

示例:(空),+ 0000,-0400,+ 1030

这与RFC 3339偏移的格式不匹配,实际上如果我们尝试%z在格式字符串中使用并解析RFC 3339日期,我们将失败:

>>> from datetime import datetime
>>> datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%f%z")
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
    (data_string, format))
ValueError: time data '2008-09-03T20:56:35.450686Z' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'
>>> datetime.strptime("2008-09-03T20:56:35.450686+05:00", "%Y-%m-%dT%H:%M:%S.%f%z")
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
    (data_string, format))
ValueError: time data '2008-09-03T20:56:35.450686+05:00' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'
Run Code Online (Sandbox Code Playgroud)

(实际上,上面就是你在Python 3中看到的内容.在Python 2中,我们会因为一个更简单的原因而失败,这在Python 2strptime根本没有实现该%z指令.)

这里的多个答案建议strptime通过Z在其格式字符串中包含一个文字来推荐所有工作,该字符串与Z问题提供者的示例日期时间字符串匹配(并丢弃它,生成datetime没有时区的对象):

>>> datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
Run Code Online (Sandbox Code Playgroud)

由于这会丢弃原始日期时间字符串中包含的时区信息,因此我们是否应该将此结果视为正确是值得怀疑的.但更重要的是,因为这种方法涉及将特定的UTC偏移硬编码到格式字符串中,所以它会在尝试使用不同的UTC偏移量解析任何RFC 3339日期时间时阻塞:

>>> datetime.strptime("2008-09-03T20:56:35.450686+05:00", "%Y-%m-%dT%H:%M:%S.%fZ")
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
    (data_string, format))
ValueError: time data '2008-09-03T20:56:35.450686+05:00' does not match format '%Y-%m-%dT%H:%M:%S.%fZ'
Run Code Online (Sandbox Code Playgroud)

除非您确定在Zulu时间内只需要支持RFC 3339日期时间,而不是其他时区偏移量,否则请不要使用strptime.请使用此处答案中描述的许多其他方法之一.

  • 令人费解的是为什么strptime没有ISO格式时区信息的指令,以及无法解析的原因.难以置信. (74认同)
  • Python 3.7 中的 `strptime()` 现在支持此答案中描述为不可能的所有内容(时区偏移中的“Z”字面量和“:”)。不幸的是,还有另一个极端情况使 RFC 3339 从根本上与 ISO 8601 不兼容,即前者允许负空时区偏移 -00:00 而后者不允许。 (6认同)
  • @CsabaToth完全同意 - 如果我有时间杀人,也许我会尝试将其添加到语言中.或者你可以这样做,如果你如此倾向 - 我看到你有一些C经验,不像我. (2认同)
  • @PeterMasiar令人难以置信,因为通常会发现python中的内容已经过深思熟虑和完全实现.我们已经被这种对细节的关注所破坏,所以当我们偶然发现"unpythonic"的语言时,我们会把玩具扔出婴儿车,就像我现在要做的那样.Whaaaaaaaaaa Whaa wahaaaaa :-( (2认同)

abc*_*ccd 135

Python 3.7+中的新功能


datetime标准库中引入了一个功能反转datetime.isoformat().

classmethod datetime.fromisoformat(date_string):

返回datetime对应date_string于其中一种格式的date.isoformat()datetime.isoformat().

具体来说,此函数支持格式的字符串:

YYYY-MM-DD[*HH[:MM[:SS[.mmm[mmm]]]][+HH:MM[:SS[.ffffff]]]]

哪里*可以匹配任何单个字符.

注意:这不支持解析任意ISO 8601字符串 - 它仅用作反向操作datetime.isoformat().

使用示例:

from datetime import datetime

date = datetime.fromisoformat('2017-01-01T12:30:59.000000')
Run Code Online (Sandbox Code Playgroud)

  • 为了正确支持`Z`,可以使用`date_string.replace("Z","+ 00:00")`修改输入脚本. (15认同)
  • 不要错过文档中的那个注释,这不接受*all*有效的ISO 8601字符串,只接受`isoformat`生成的字符串.它不接受问题"2008-09-03T20:56:35.450686Z"中的例子,因为尾随`Z`,但它确实接受``2008-09-03T20:56:35.450686"`. (13认同)
  • 那真是怪了.因为`datetime`可能包含`tzinfo`,因此输出一个时区,但`datetime.fromisoformat()`不解析tzinfo?好像是个bug .. (4认同)
  • @kevinarpe 不,“datetime.fromisoformat”似乎需要另一种格式。我刚刚测试了这两个版本,虽然它与 `+00:00` 一起工作正常,但我得到 _"ValueError: Invalid isoformat string"_ with `+0000`。 (4认同)
  • 请注意,在几秒钟内,它只能处理0、3或6个小数位。如果输入数据具有1、2、4、5、7或更多的小数位,则解析将失败! (3认同)
  • `fromisoformat` 现在接受 Python 3.11 中几乎所有 ISO 8601 日期字符串,因此很多注释都已经过时了。 (2认同)

Nic*_*ley 72

试试iso8601模块; 它正是这样做的.

python.org wiki 上的WorkingWithTime页面上提到了其他几个选项.

  • [iso8601](https://pypi.python.org/pypi/iso8601/),又名*pyiso8601*,最近于2014年2月更新.最新版本支持更广泛的ISO 8601字符串集.在我的一些项目中,我一直在使用效果很好. (6认同)
  • 问题不是"我如何解析ISO 8601日期",而是"如何解析这个确切的日期格式". (3认同)
  • @tiktak OP问"我需要解析像X这样的字符串",我对这两个库的回复就是使用另一个,因为iso8601仍然有重要的问题.我在这样一个项目中的参与或缺乏与答案完全无关. (3认同)
  • 请注意,iso8601的pip版本自2007年以来一直没有更新,并且有一些非常突出的错误.我建议你自己应用一些关键的补丁或找到已经完成的许多github分支中的一个https://github.com/keithhackbarth/pyiso8601-strict (2认同)
  • 遗憾的是,pypi 上名为“iso8601”的库根本不完整。它明确指出它不处理基于周数的日期,仅举一个例子。 (2认同)

小智 34

import re,datetime
s="2008-09-03T20:56:35.450686Z"
d=datetime.datetime(*map(int, re.split('[^\d]', s)[:-1]))

  • 我不同意,这实际上是不可读的,据我所知,没有考虑到Zulu(Z),即使提供了时区数据,这也使得这个日期时间变得幼稚. (73认同)
  • 我觉得它很可读.实际上,它可能是最简单,性能最佳的转换方式,无需安装其他软件包. (14认同)
  • 变体:`datetime.datetime(*map(int,re.findall('\ d +',s))` (4认同)
  • 这导致一个没有时区的天真的日期时间对象,对吧?那么UTC位在翻译中会丢失吗? (3认同)
  • 这相当于d = datetime.datetime(*map(int,re.split('\ D',s)[: - 1]))我想. (2认同)

tzo*_*zot 30

你得到的确切错误是什么?它像下面这样吗?

>>> datetime.datetime.strptime("2008-08-12T12:20:30.656234Z", "%Y-%m-%dT%H:%M:%S.Z")
ValueError: time data did not match format:  data=2008-08-12T12:20:30.656234Z  fmt=%Y-%m-%dT%H:%M:%S.Z
Run Code Online (Sandbox Code Playgroud)

如果是,您可以将输入字符串拆分为".",然后将微秒添加到您获得的日期时间.

试试这个:

>>> def gt(dt_str):
        dt, _, us= dt_str.partition(".")
        dt= datetime.datetime.strptime(dt, "%Y-%m-%dT%H:%M:%S")
        us= int(us.rstrip("Z"), 10)
        return dt + datetime.timedelta(microseconds=us)

>>> gt("2008-08-12T12:20:30.656234Z")
datetime.datetime(2008, 8, 12, 12, 20, 30, 656234)
Run Code Online (Sandbox Code Playgroud)

  • 你不能只剥离.Z,因为它意味着时区,可以是不同的.我需要将日期转换为UTC时区. (8认同)
  • 另外,"%f"是微秒说明符,因此(时区初始的)strptime字符串看起来像:"%Y-%m-%dT%H:%M:%S.%f". (8认同)

MrF*_*pes 24

来自其中一条评论的一个简单选项:替换'Z''+00:00'- 并使用 Python 3.7+ fromisoformat

from datetime import datetime

s = "2008-09-03T20:56:35.450686Z"

datetime.fromisoformat(s.replace('Z', '+00:00'))
# datetime.datetime(2008, 9, 3, 20, 56, 35, 450686, tzinfo=datetime.timezone.utc)
Run Code Online (Sandbox Code Playgroud)

虽然strptime可以将'Z'字符解析为 UTC,但fromisoformat速度要快 ~ x40(另请参阅:更快的 strptime):

%timeit datetime.fromisoformat(s.replace('Z', '+00:00'))
346 ns ± 22.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit datetime.strptime(s, '%Y-%m-%dT%H:%M:%S.%f%z')
14.2 µs ± 452 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit dateutil.parser.parse(s)
80.1 µs ± 3.32 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Run Code Online (Sandbox Code Playgroud)

(Windows 10 上的 Python 3.8.7 x64)

  • @mikerodent:重点是“fromisoformat”将“+00:00”而不是“Z”解析为[aware datetime](https://docs.python.org/3/library/datetime.html#aware-and- naive-objects),tzinfo 为 UTC。如果您的输入例如以“Z+00:00”结尾,您可以在将其输入“fromisoformat”之前删除“Z”。其他 UTC 偏移量(例如“+05:30”)将被解析为静态 UTC 偏移量(不是实际时区)。 (2认同)

小智 19

在这些日子里,Arrow也可以用作第三方解决方案:

>>> import arrow
>>> date = arrow.get("2008-09-03T20:56:35.450686Z")
>>> date.datetime
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686, tzinfo=tzutc())
Run Code Online (Sandbox Code Playgroud)

  • Arrow虽然不能正确支持ISO8601:https://github.com/crsmithdev/arrow/issues/291 (6认同)
  • 只需使用 python-dateutil - 箭头需要 python-dateutil。 (2认同)

And*_*ous 19

从Python 3.7开始,strptime支持UTC偏移()中的冒号分隔符.所以你可以使用:

import datetime
datetime.datetime.strptime('2018-01-31T09:24:31.488670+00:00', '%Y-%m-%dT%H:%M:%S.%f%z')
Run Code Online (Sandbox Code Playgroud)

  • @MarkAmery:Python 3.11 进一步改进了 `fromisoformat()`,它现在可以处理 `Z` 时区:`datetime.fromisoformat('2018-01-31T09:24:31Z')` 生成 `datetime.datetime(2018, 1, 31, 9, 24, 31, tzinfo=datetime.timezone.utc)`。 (3认同)
  • 但是在3.7中,您*还*具有`datetime.fromisoformat()`,它可以像输入一样自动处理字符串:`datetime.datetime.isoformat('2018-01-31T09:24:31.488670 + 00:00')`。 (2认同)
  • 好点子。我同意,我建议使用`datetime.fromisoformat()`和`datetime.isoformat()` (2认同)

Bla*_*g23 16

只需使用python-dateutil模块:

>>> import dateutil.parser as dp
>>> t = '1984-06-02T19:05:00.000Z'
>>> parsed_t = dp.parse(t)
>>> print(parsed_t)
datetime.datetime(1984, 6, 2, 19, 5, tzinfo=tzutc())
Run Code Online (Sandbox Code Playgroud)

文档


enc*_*ter 13

如果您不想使用dateutil,可以尝试以下功能:

def from_utc(utcTime,fmt="%Y-%m-%dT%H:%M:%S.%fZ"):
    """
    Convert UTC time string to time.struct_time
    """
    # change datetime.datetime to time, return time.struct_time type
    return datetime.datetime.strptime(utcTime, fmt)
Run Code Online (Sandbox Code Playgroud)

测试:

from_utc("2007-03-04T21:08:12.123Z")
Run Code Online (Sandbox Code Playgroud)

结果:

datetime.datetime(2007, 3, 4, 21, 8, 12, 123000)
Run Code Online (Sandbox Code Playgroud)

  • 这个答案依赖于将特定的UTC偏移(即"Z",即+00:00)硬编码到传递给`strptime`的格式字符串中.这是一个坏主意,因为它将无法使用不同的UTC偏移量解析任何日期时间并引发异常.请参阅[我的回答](http://stackoverflow.com/a/30696682/1709587),其中描述了如何使用strptime解析RFC 3339实际上是不可能的. (5认同)

Don*_*kby 11

如果你正在使用Django,它提供了dateparse模块,它接受一系列类似于ISO格式的格式,包括时区.

如果您不使用Django而您不想使用此处提到的其他库,则可以将dateparse的Django源代码调整到您的项目中.


mov*_*yer 9

我发现ciso8601是解析ISO 8601时间戳的最快方法.顾名思义,它是用C实现的.

import ciso8601
ciso8601.parse_datetime('2014-01-09T21:48:00.921000+05:30')
Run Code Online (Sandbox Code Playgroud)

与其他答案中列出的所有其他库相比,GitHub Repo README显示其速度提高了10倍.

我的个人项目涉及很多ISO 8601解析.很高兴能够只是拨打电话并快10倍.:)

编辑:我已成为ciso8601的维护者.现在比以往任何时候都快!

  • @hamx0r,请注意`datetime.strptime()` 不是完整的 ISO 8601 解析库。如果你使用的是 Python 3.7,你可以使用 `datetime.fromisoformat()` 方法,它更灵活一些。您可能 [对这个更完整的解析器列表感兴趣](https://github.com/closeio/ciso8601/blob/benchmarking/README.rst#benchmark),它应该很快被合并到 ciso8601 README 中。 (3认同)
  • @Dirk,[仅在 Python 2 中](https://github.com/closeio/ciso8601#dependency-on-pytz-python-2)。但即使在下一个版本中[应该删除](https://github.com/closeio/ciso8601/pull/58)。 (2认同)

Mar*_*son 7

我是iso8601 utils的作者.它可以在GitHubPyPI 上找到.以下是解析示例的方法:

>>> from iso8601utils import parsers
>>> parsers.datetime('2008-09-03T20:56:35.450686Z')
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
Run Code Online (Sandbox Code Playgroud)


zaw*_*uza 7

另一种方法是使用 ISO-8601 的专用解析器,即使用dateutil 解析器的isoparse函数:

from dateutil import parser

date = parser.isoparse("2008-09-03T20:56:35.450686+01:00")
print(date)
Run Code Online (Sandbox Code Playgroud)

输出:

2008-09-03 20:56:35.450686+01:00
Run Code Online (Sandbox Code Playgroud)

标准 Python 函数datetime.fromisoformat的文档中也提到了此函数:

第三方包 dateutil 中提供了功能更全的 ISO 8601 解析器 dateutil.parser.isoparse。


box*_*xed 6

我为ISO 8601标准编写了一个解析器并将其放在GitHub上:https://github.com/boxed/iso8601.此实现支持规范中的所有内容,但持续时间,间隔,周期间隔以及Python日期时间模块支持的日期范围之外的日期除外.

测试包括在内!:P

  • 通常,指向工具或库的链接[应附有使用说明,链接资源如何适用于问题的具体说明,或某些示例代码](http://stackoverflow.com/a/251605/584192) ,或者如果可能的话,以上所有. (2认同)

Ben*_*ggs 6

这适用于从Python 3.2开始的stdlib(假设所有时间戳均为UTC):

from datetime import datetime, timezone, timedelta
datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S.%fZ").replace(
    tzinfo=timezone(timedelta(0)))
Run Code Online (Sandbox Code Playgroud)

例如,

>>> datetime.utcnow().replace(tzinfo=timezone(timedelta(0)))
... datetime.datetime(2015, 3, 11, 6, 2, 47, 879129, tzinfo=datetime.timezone.utc)
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用`timezone.utc`代替`timezone(timedelta(0))`。另外,如果您[提供`utc` tzinfo对象](http://stackoverflow.com/a/2331635/4279),则该代码也可以在python 2.6+中运行(至少)。 (4认同)
  • 该答案取决于将特定的UTC偏移量(即“ Z”,表示+00:00)硬编码为传递给`strptime`的格式字符串。这是一个坏主意,因为它将无法解析具有不同UTC偏移量的任何日期时间并引发异常。请参阅[我的答案](http://stackoverflow.com/a/30696682/1709587),其中描述了实际上如何用strptime解析RFC 3339。 (2认同)

Dam*_*ick 6

datetime.datetime在不安装第三方模块的情况下,将类似ISO 8601的日期字符串转换为所有支持的Python版本中的UNIX时间戳或对象的一种简单方法是使用SQLite日期解析器.

#!/usr/bin/env python
from __future__ import with_statement, division, print_function
import sqlite3
import datetime

testtimes = [
    "2016-08-25T16:01:26.123456Z",
    "2016-08-25T16:01:29",
]
db = sqlite3.connect(":memory:")
c = db.cursor()
for timestring in testtimes:
    c.execute("SELECT strftime('%s', ?)", (timestring,))
    converted = c.fetchone()[0]
    print("%s is %s after epoch" % (timestring, converted))
    dt = datetime.datetime.fromtimestamp(int(converted))
    print("datetime is %s" % dt)
Run Code Online (Sandbox Code Playgroud)

输出:

2016-08-25T16:01:26.123456Z is 1472140886 after epoch
datetime is 2016-08-25 12:01:26
2016-08-25T16:01:29 is 1472140889 after epoch
datetime is 2016-08-25 12:01:29
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.这太恶心了.我喜欢它. (9认同)

小智 6

Django的parse_datetime()函数支持UTC偏移的日期:

parse_datetime('2016-08-09T15:12:03.65478Z') =
datetime.datetime(2016, 8, 9, 15, 12, 3, 654780, tzinfo=<UTC>)
Run Code Online (Sandbox Code Playgroud)

因此,它可用于在整个项目中的字段中解析ISO 8601日期:

from django.utils import formats
from django.forms.fields import DateTimeField
from django.utils.dateparse import parse_datetime

class DateTimeFieldFixed(DateTimeField):
    def strptime(self, value, format):
        if format == 'iso-8601':
            return parse_datetime(value)
        return super().strptime(value, format)

DateTimeField.strptime = DateTimeFieldFixed.strptime
formats.ISO_INPUT_FORMATS['DATETIME_INPUT_FORMATS'].insert(0, 'iso-8601')
Run Code Online (Sandbox Code Playgroud)


Mic*_*ner 5

如果pandas无论如何使用,我可以Timestamp推荐pandas。在那里你可以

ts_1 = pd.Timestamp('2020-02-18T04:27:58.000Z')    
ts_2 = pd.Timestamp('2020-02-18T04:27:58.000')
Run Code Online (Sandbox Code Playgroud)

Rant:令人难以置信的是,我们在 2021 年仍然需要​​担心日期字符串解析之类的问题。

  • 请参阅 [Paul Ganssle 的咆哮](https://github.com/pandas-dev/pandas/issues/37654)。至于不兼容,请同时执行 `datetime.fromisoformat('2021-01-01T00:00:00+01:00').tzinfo.utc` 和 `pandas.Timestamp('2021-01-01T00:00:00+01 :00').tzinfo.utc` : 完全不一样。 (2认同)