如何在没有dateutil的情况下将时区感知字符串转换为python中的datetime?

lxy*_*xyu 60 python timezone datetime rfc3339

我必须将时区感知字符串转换为python datetime对象.

例如2012-11-01T04:16:13-04:00.

我发现有一个dateutil模块具有解析函数来执行它,但我真的不想使用它,因为它添加了一个依赖项.

那我该怎么办呢?我尝试了类似下面的东西,但没有运气.

datetime.datetime.strptime("2012-11-01T04:16:13-04:00", "%Y-%m-%dT%H:%M:%S%Z")
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 64

从Python 3.7开始,datetime.datetime.fromisoformat()可以处理您的格式:

>>> import datetime
>>> datetime.datetime.fromisoformat('2012-11-01T04:16:13-04:00')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))
Run Code Online (Sandbox Code Playgroud)

在较旧的Python版本中,你不能,不是没有很多艰苦的手动时区定义.

Python不包含时区数据库,因为它过时会过时.相反,Python依赖外部库,它可以有更快的发布周期,为您提供正确配置的时区.

作为副作用,这意味着时区解析也需要是外部库.如果dateutil你的重量太重,请改用iso8601它,它会解析你的特定格式:

>>> import iso8601
>>> iso8601.parse_date('2012-11-01T04:16:13-04:00')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=<FixedOffset '-04:00'>)
Run Code Online (Sandbox Code Playgroud)

iso8601是一个惊人的 4KB小.比较那个python-dateutil148KB.

从Python 3.2开始,Python 可以处理简单的基于偏移的时区,并将在时间戳中%z解析-hhmm+hhmm时区偏移.这意味着对于ISO 8601时间戳,您必须删除:时区:

>>> from datetime import datetime
>>> iso_ts = '2012-11-01T04:16:13-04:00'
>>> datetime.strptime(''.join(iso_ts.rsplit(':', 1)), '%Y-%m-%dT%H:%M:%S%z')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000)))
Run Code Online (Sandbox Code Playgroud)

Python问题15873中正在跟踪缺少正确的ISO 8601解析.

  • @Jashwant:在任何Python版本中它都会失败。如果必须使用 `Z` 接受字符串,请使用 `isoformattedstring.replace("Z", "+00:00")`。不确定*十进制时间*是什么意思。 (2认同)

Moh*_*med 38

这是使用dateutil包的datetime对象的Python Doc ..

from dateutil.parser import parse

get_date_obj = parse("2012-11-01T04:16:13-04:00")
print get_date_obj
Run Code Online (Sandbox Code Playgroud)

  • @Paullo python-dateutil 正是“外部库”。 (9认同)
  • 这应该是在没有外部lib的情况下执行此操作的正确答案 (4认同)

Jam*_*zuy 17

原始问题中的代码有两个问题::时区中不应有 a并且“时区作为偏移量”的格式字符串是小写%z而不是大写%Z

这在Python v3.6 中对我有用

>>> from datetime import datetime
>>> t = datetime.strptime("2012-11-01T04:16:13-0400", "%Y-%m-%dT%H:%M:%S%z")
>>> print(t)
2012-11-01 04:16:13-04:00
Run Code Online (Sandbox Code Playgroud)

  • 在时区有一个冒号并没有错。许多来源以字符串形式显示他们的时间:`2012-11-01T04:16:13-04:00`。OP 正在寻求解析该表单。 (4认同)

小智 8

你可以这样转换。

date = datetime.datetime.strptime('2019-3-16T5-49-52-595Z','%Y-%m-%dT%H-%M-%S-%f%z')
date_time = date.strftime('%Y-%m-%dT%H:%M:%S.%fZ')
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以创建一个时区感知对象并稍后替换tzinfo并使其成为时区感知DateTime对象。

from datetime import datetime
import pytz

unaware_time = datetime.strptime("2012-11-01 04:16:13", "%Y-%m-%d %H:%M:%S")
aware_time = unaware_time.replace(tzinfo=pytz.UTC)
Run Code Online (Sandbox Code Playgroud)