【问题标题】:pytz - Converting UTC and timezone to local timepytz - 将 UTC 和时区转换为本地时间
【发布时间】:2014-10-05 13:15:44
【问题描述】:

我在 UTC 时区有一个datetime,例如:

utc_time = datetime.datetime.utcnow()

还有一个 pytz 时区对象:

tz = timezone('America/St_Johns')

utc_time 转换为给定时区的正确方法是什么?

【问题讨论】:

标签: python timezone utc pytz


【解决方案1】:

我想我明白了:

pytz.utc.localize(utc_time, is_dst=None).astimezone(tz)

此行首先将天真的(不知道时区)utc_timedatetime 对象转换为包含时区 (UTC) 的 datetime 对象。然后它使用astimezone函数根据请求的时区调整时间。

【讨论】:

  • utc_time.replace(tzinfo=pytz.utc).astimezone(tz)。注意:pytz.utc 是一种特殊情况(始终为零 UTC 偏移量)。在这种情况下,您不需要localize() 呼叫。如果你保留它(为了一般性);然后在表达式周围添加tz.normalize() call (it might be necessary if the source timezone is not UTC)。
  • @J.F.Sebastian 需要调用localize,因为utc_time 不包含时区信息。没有它astimezone 将无法工作。
  • @Tzach 你认为replace() 调用在我之前的评论中有什么作用?
  • 它也适用于 utc_timestamp 作为 int 和 datetime.utcfromtimestamp(utc_timestamp),它返回一个不知道时区的日期时间对象。但是 utc_time.replace 不做时间转换,只添加一个 tzinfo。
  • @YingdingWang 差不多5年前的问题是没有使用utcfromtimestampdatetime.datetime.utcnow() 也将 tzinfo 设置为 None。
【解决方案2】:

这就是fromutc函数的确切用途:

tz.fromutc(utc_time)

astimezone 函数在后台调用 fromutc,但首先尝试转换为 UTC,这在您的情况下是不需要的)

【讨论】:

    【解决方案3】:

    我同意 Tzach 的回答。只是想包含 is_dst 参数不是必需的:

    pytz.utc.localize(datetime.utcnow()).astimezone(tz)
    

    该代码将当前 UTC 时间转换为可识别时区的当前日期时间。

    而下面的代码将当前 UTC 时间转换为不一定是当前的时区感知日期时间。时区只是附加到 UTC 时间值中。

    tz.localize(datetime.utcnow())
    

    【讨论】:

    • 如果你已经有一个时区感知的日期时间,那么你只需要使用astimezone:dt.astimezone(tz)。另见this answerpytz docs
    • user8808265 的回答要简单得多。
    【解决方案4】:

    我可以推荐使用arrow吗?如果我理解了这个问题:

    >>> import arrow
    >>> utc = arrow.utcnow()
    >>> utc
    <Arrow [2014-08-12T13:01:28.071624+00:00]>    
    >>> local = utc.to("America/St_Johns")
    >>> local
    <Arrow [2014-08-12T10:31:28.071624-02:30]>
    

    你也可以使用

    tz.fromutc(utc_time)
    

    【讨论】:

    • 谢谢。这个库确实看起来是datetime 的一个很好的替代品,但是我的项目很大,我不想通过使用另一个日期时间库来造成更多的混乱。我一定会考虑在其他项目中使用它。
    【解决方案5】:

    另一种非常简单的方法:

    因为utcnow方法返回一个naive对象,所以你必须把naive对象转换成aware对象。使用replace 方法,您可以将 naive 对象转换为 aware 对象。然后您可以使用astimezone 方法在不同的时区创建新的日期时间对象。

    from datetime import datetime
    import pytz    
    utc_time = datetime.utcnow()
    tz = pytz.timezone('America/St_Johns')
    
    utc_time =utc_time.replace(tzinfo=pytz.UTC) #replace method      
    st_john_time=utc_time.astimezone(tz)        #astimezone method
    print(st_john_time)
    

    【讨论】:

    • 替换方法是个坏主意。它的行为是随机的
    【解决方案6】:

    您也可以使用下面的示例,我将它用于类似的任务

    tz = pytz.timezone('America/St_Johns')
    time_difference=tz.utcoffset(utc_time).total_seconds() #time difference between UTC and local timezones in 5:30:00 format
    utc_time = date + timedelta(0,time_difference)
    

    它运行速度很快,您无需导入额外的库。

    【讨论】:

    • 这对于夏令时的时区是错误的,因为它没有考虑到它们。见this answer
    猜你喜欢
    • 2019-05-31
    • 2017-03-10
    • 1970-01-01
    • 2012-11-01
    • 2021-08-02
    • 2013-08-26
    • 1970-01-01
    • 2019-03-09
    • 2018-07-27
    相关资源
    最近更新 更多