如何在python中将时区添加到天真的日期时间实例中

wai*_*kuo 35 python timezone datetime pytz

我有一个datetime没有时区信息.我现在正在获取时区信息,并希望将时区添加到现有的datetime实例中,我该怎么办?

d = datetime.datetime.now()
tz = pytz.timezone('Asia/Taipei')
Run Code Online (Sandbox Code Playgroud)

如何将时区信息添加tz到datetimea

Mar*_*ers 59

使用tz.localize(d)本地化的实例.从文档:

第一种是使用pytz库提供的localize()方法.这用于本地化一个天真的日期时间(没有时区信息的日期时间):

>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0))
>>> print(loc_dt.strftime(fmt))
2002-10-27 06:00:00 EST-0500
Run Code Online (Sandbox Code Playgroud)

如果您使用tz.localize(),但使用datetime.replace(),则可能会使用历史偏移; tz.localize()将为给定日期选择正确的偏移量.例如,美国东部时区DST开始和结束日期随时间而变化.

当您尝试本地化一个不明确的日期时间值,因为它跨越从夏季到冬季的过渡期,反之亦然,将查询时区以查看生成的日期时间对象是否应.dst()返回True或False.您可以使用is_dst关键字参数覆盖时区的默认值.localize():

dt = tz.localize(naive, is_dst=True)
Run Code Online (Sandbox Code Playgroud)

甚至可以通过设置完全关闭选择is_dst=None.在这种情况下,或在极少数情况下有没有默认的时区设置,不明确的日期时间值会导致AmbiguousTimeError被引发的异常.is_dst仅为不明确的日期时间值查询该标志,否则将忽略该标志.

要以另一种方式返回,将时区感知对象转回原始对象,请使用.replace(tzinfo=None):

naivedt = awaredt.replace(tzinfo=None)
Run Code Online (Sandbox Code Playgroud)

  • @waitingkuo:在`datetime`对象上调用`.replace(tzinfo = None)`.返回值是一个天真的`datetime`实例. (4认同)
  • @hobs:将`.replace()`与`pytz`时区一起使用是错误的,这个时区可能有多个utc偏移(很多时区都有).默认的tzinfo对象通常对应于LMT(太阳时),这在大多数情况下都不是你想要的(我认为默认背后的原因是为了帮助揭示不正确的`.replace()`用法). (3认同)

hob*_*obs 7

如果您知道原始日期时间是在尝试添加的时区中“测量”的,则可以(但可能不应该)使用replace而不是localize

# d = datetime.datetime.now()
# tz = pytz.timezone('Asia/Taipei')
d = d.replace(tzinfo=tz)
Run Code Online (Sandbox Code Playgroud)

我可以想象两次可能有意义的事情(第二次发生在我身上):

  1. 您的服务器区域设置设置为不正确的时区,并且您正在尝试datetime通过使实例意识到该不正确的时区来纠正实例(并且可能稍后将其本地化为“正确”的时区,因此now()的值与其他时区匹配)您与之比较的时间(也许是您的手表)
  2. 您想用时区(tzinfo)属性“标记” time实例(不是 a datetime),以便以后可以使用该属性形成完整的datetime实例。

  • 4. 您已经使用 utcnow 生成了 utc 时间,这是 tz-naive,并且您需要将其与 tx-aware 时间进行比较。 (3认同)
  • 3. 您从数据库中检索了一个日期时间,其中该列是简单的,但您知道它存储在的 TZ,并且您希望在检索后对其进行操作。 (2认同)