【问题标题】:Python (datetime) timezone conversion off by 4 minutesPython(日期时间)时区转换关闭 4 分钟
【发布时间】:2020-07-14 16:44:13
【问题描述】:

当我运行这段代码时:

#!/usr/bin/env python3
from datetime import datetime, timedelta
from dateutil import tz
from pytz import timezone

time = "2020-01-15 10:14:00"
time = datetime.strptime(time, "%Y-%m-%d %H:%M:%S")

print("time1 = " + str(time))

time = time.replace(tzinfo=timezone('America/New_York'))
print("time2 = " + str(time))

time = time.astimezone(tz.gettz('UTC')) # explicity convert to UTC time
print("time3 = " + str(time))

time = datetime.strftime(time, "%Y-%m-%d %H:%M:%S")  # output format
print("done time4 = " + str(time))

我得到这个输出:

time1 = 2020-01-15 10:14:00
time2 = 2020-01-15 10:14:00-04:56
time3 = 2020-01-15 15:10:00+00:00
done time4 = 2020-01-15 15:10:00

我原以为最后的时间是“2020-01-15 15:14:00”,有人知道为什么它会延迟 4 分钟吗?我不明白为什么 time2 中的偏移量会是“-04:56”而不是“-05:00”

【问题讨论】:

标签: python datetime timezone utc


【解决方案1】:

From pytz documentation:

这个库不同于记录在案的用于 tzinfo 实现的 Python API;如果您想创建本地挂钟时间,您需要使用本文档中记录的localize() 方法。此外,如果您对跨越 DST 边界的本地时间执行日期算术,则结果可能位于不正确的时区(即,从 2002-10-27 1:00 EST 减去 1 分钟,您会得到 2002-10-27 0: 59 EST 而不是正确的 2002-10-27 1:59 EDT)。

所以,你错误地使用了 pytz。

以下是正确和错误的代码 以下代码显示了您使用 pytz (datetime.replace(tzinfo=pytz.timezone)) 的结果,以及使用带有 datetime 的 pytz 的推荐方式 (pytz.timezone.localize(datetime))。p>

from datetime import datetime, date, time, timezone
from dateutil import tz
import pytz


d = date(2019, 1, 27)
t = time(19, 32, 00)

t1 = datetime.combine(d, t)
t1_epoch = t1.timestamp()
print("t1_epoch " + str(t1_epoch))
print("t1 " + str(t1))


# your approach/code
nytz = pytz.timezone('America/New_York')
t3 = t1.replace(tzinfo=nytz)
t3_epoch = t3.timestamp()
print("t3_epoch " + str(t3_epoch))
print("t3 " + str(t3))

# recommended approach/code using localize
nytz = pytz.timezone('America/New_York')
t6 = nytz.localize(t1)
t6_epoch = t6.timestamp()
print("t6_epoch " + str(t6_epoch))
print("t6 " + str(t6))

以上代码的输出:

t1_epoch 1548617520.0
t1 2019-01-27 19:32:00
t3_epoch 1548635280.0
t3 2019-01-27 19:32:00-04:56
t6_epoch 1548635520.0
t6 2019-01-27 19:32:00-05:00

t3 是您正在做的事情,它给出的偏移量不正确(-4:56)。请注意,在这种情况下,POSIX 时间也是不正确的。根据定义,POSIX 时间不随时区变化。

t6 已使用 pytz.timezone.localize() 方法创建,并提供正确的 UTC 偏移量 (-5:00)。

更新:将答案的语言更新为one user found the answer confusing

【讨论】:

  • 虽然正确,但答案对我来说似乎相当混乱(正确和错误的代码?)。基本上,答案是:使用pytz 模块的timezone 类中的localize(),而不是datetime 类中的replace()。顺便说一句,要检查 UTC 偏移量,您可以简单地使用 dt.utcoffset() / timedelta(hours=1)(假设 dt 是有意识的 datetime 对象)。
  • @MrFuppes 我更新了“正确和错误的代码”部分以避免混淆(尽管有一个连续的逗号来消除歧义)。是的,我们可以使用您建议的代码进行抵消。 OP 已经在使用str(datetime.datetime),因此显示偏移量是有意义的。
  • @narendra-choudhary 你是最棒的!非常感谢:)
【解决方案2】:

我知道这是一个旧线程,但是我今天在将日期从 America/Sao_Paulo 时区向前和向后转换为 UTC 时遇到了这个确切的问题。但就我而言,它延迟了 6 分钟。

合并@narendra-choudhary 提供的解决方案我得到了这个:

import pytz
from datetime import datetime
# Simulating unaware date created by user in front-end
in_date = datetime.now()
z = pytz.timezone("America/Sao_Paulo")
aware_localized_date = z.localize(in_date)
# Now converting to UTC
utc_date = aware_localized_date.astimezone(pytz.UTC)
print(utc_date.strftime("%d/%m/%Y %H:%M:%S"))
print(in_date.strftime("%d/%m/%Y %H:%M:%S"))

输出是:

>>> print(utc_date.strftime("%d/%m/%Y %H:%M:%S"))
11/06/2021 21:56:02
>>> print(in_date.strftime("%d/%m/%Y %H:%M:%S"))
11/06/2021 18:56:02
>>>

感谢@narendra-choudhary,我的代码现在可以运行了!希望对困惑的人有所帮助。

【讨论】:

  • python datetime timezone Conversion off 6 分钟希望 google spy bots 得到这个
  • 使用datetime.now(pytz.timezone("America/Sao_Paulo")) 既安全又简单——这是您不需要使用 pytz 的时区类显式本地化的场合之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-28
相关资源
最近更新 更多