【问题标题】:pytz and astimezone() cannot be applied to a naive datetimepytz 和 astimezone() 不能应用于天真的日期时间
【发布时间】:2012-09-19 12:20:37
【问题描述】:

我有一个日期,我需要让它知道时区。

local_tz = timezone('Asia/Tokyo')
start_date = '2012-09-27'
start_date = datetime.strptime(start_date, "%Y-%m-%d")   
start_date = start_date.astimezone(local_tz)


now_utc = datetime.now(timezone('UTC'))
local_now = now_utc.astimezone(local_tz)

我需要看看这是不是真的:

print start_date>local_now

但我收到此错误。

   start_date = start_date.astimezone(local_tz)
   ValueError: astimezone() cannot be applied to a naive datetime

我将 UTC 转换为东京没有问题。我需要在东京制作 start_date 时区感知广告。

谢谢

【问题讨论】:

  • 从 3.6 版开始,astimezone 可以与 naive(时区未知)日期时间一起使用。如果您仍在使用较低版本 (

标签: python datetime timezone pytz


【解决方案1】:

对于pytz 时区,使用他们的.localize() 方法将一个天真的datetime 对象变成一个带有时区的对象:

start_date = local_tz.localize(start_date)

对于没有 DST 转换的时区,将时区附加到天真的 datetime 对象的 .replace() method 通常也可以工作:

start_date = start_date.replace(tzinfo=local_tz)

有关详细信息,请参阅 pytz 文档的 localized times and date arithmetic

【讨论】:

  • pytz docs 说在许多时区直接使用 tzinfo 属性会失败。应该使用 tz.localize()。
  • @J.F.Sebastian 是一个很好的例子来说明它会失败的严重程度,请参阅 stackoverflow.com/questions/11442183/… 并注意它与 DST 无关。
  • @J.F.Sebastian:很有趣。更新了答案。
  • @MarkRansom:我知道。 pytz 以“欧洲/阿姆斯特丹”为例。
  • python 的另一个 WTF!
【解决方案2】:

您可以使用local_tz.localize(naive_dt, is_dst=None) 将天真的日期时间对象转换为时区感知对象。

from datetime import datetime
import pytz

local_tz = pytz.timezone('Asia/Tokyo')

start_date = local_tz.localize(datetime(2012, 9, 27), is_dst=None)
now_utc = datetime.utcnow().replace(tzinfo=pytz.utc)

print start_date > now_utc

is_dst=None 强制 .localize() 如果给定的本地时间不明确,则引发异常。

【讨论】:

    【解决方案3】:

    如果您使用的是 Django Rest Framework,您可以覆盖 DateTimeField 类,例如:

    class DateTimeFieldOverridden(serializers.DateTimeField):
    
    def to_representation(self, value):
        local_tz = pytz.timezone(TIME_ZONE)
        value = local_tz.localize(value)
        return super(DateTimeFieldOverridden, self).to_representation(value)
    

    你在你的序列化器中这样使用它:

    date_time = DateTimeFieldOverridden(format='%d-%b-%Y', read_only=True)
    

    希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-11-15
      • 2012-05-05
      • 2023-01-13
      • 2010-10-22
      • 2012-12-27
      • 2021-07-07
      • 1970-01-01
      • 2017-09-30
      相关资源
      最近更新 更多