模块pytz:UTC减少而不是增加

Posted

技术标签:

【中文标题】模块pytz:UTC减少而不是增加【英文标题】:Module pytz: UTC decrease instead of increase 【发布时间】:2019-07-23 15:40:49 【问题描述】:

编辑: 我想在我的国家 UTC(西班牙)转换 UTC 时间。 我正在使用模块 pytz 进行转换,但我得到的结果是 UTC-1 而不是 UTC+1。这是我的代码:

import datetime
import pytz

madrid = pytz.timezone("Europe/Madrid")
UTC_time = datetime.datetime.strptime("2019-03-01 14:45","%Y-%m-%d %H:%M")
madrid_dt = madrid.localize(UTC_time, is_dst=None)
MadridTime = madrid_dt.astimezone(pytz.utc).strftime ("%Y-%m-%d %H:%M")

这是输出:

UTC_Time: 2019-03-01 14:45:00
MadridTime: 2019-03-01 13:45

我需要马德里时间返回 15:45 而不是 13:45。我做错了什么?

EDITED2:在您的帮助下,我发现我对 localize 和 astimeszone 的使用感到困惑。现在我面临两个新问题。这是新代码:

import datetime
import pytz

dt = datetime.datetime.strptime('2019-03-01 14:45','%Y-%m-%d %H:%M')

madrid_tz = pytz.timezone('Europe/Madrid')
madrid = dt.astimezone(madrid_tz)

print(madrid)
# 2019-03-01 14:45:00+01:00

print(madrid.strftime ("%Y-%m-%d %H:%M"))
# 2019-03-01 14:45

问题 1:在 Windows 10、Python3 中运行此代码,我期望的输出是 2019-03-01 15:45:00 而不是 2019-03-01 14:45:00+01:00。我尝试使用strftime ("%Y-%m-%d %H:%M")对其进行格式化,但这并没有成功。

问题 2:在 Raspberrypi 中运行此代码(完成后我将在其中运行代码),Python3,我在这一行 madrid = dt.astimezone(madrid_tz) 中得到一个 ValueError。错误是ValueError: astimezone() cannot be applied to a naive datetime

有什么想法吗?

【问题讨论】:

2 小时轮班看起来像夏令时问题。 你为什么使用is_dst=None?有什么具体原因吗? 我会尝试local.localize(TheTime, is_dst=True),但这是在黑暗中拍摄 【参考方案1】:

我认为您误解了 localizeastimezone,因为您使用 localize 在欧洲/马德里时区创建 2019-03-01 14:45 日期时间对象,然后使用 @ 将其转换为 UTC 987654324@ 给你意想不到的结果。

相反,您似乎打算为 2019-03-01 14:45 创建一个日期时间对象,然后您想以欧洲/马德里时间和 UTC 时间显示该日期时间。您可以使用astimezonelocalize 来获得所需的结果。

astimezone 示例:

import datetime
import pytz

dt = datetime.datetime.strptime('2019-03-01 14:45','%Y-%m-%d %H:%M')

madrid_tz = pytz.timezone('Europe/Madrid')
madrid = dt.astimezone(madrid_tz)
print(madrid)
# 2019-03-01 15:45:00+01:00

utc = dt.astimezone(pytz.utc)
print(utc)
# 2019-03-01 14:45:00+00:00

localize 示例(请注意,datetime 对象是在每个时区对应的时间创建的,因此两者将代表相同的时间点):

import datetime
import pytz

madrid_tz = pytz.timezone('Europe/Madrid')
madrid = madrid_tz.localize(datetime.datetime(2019, 3, 1, 15, 45))
print(madrid)
# 2019-03-01 15:45:00+01:00

utc = pytz.utc.localize(datetime.datetime(2019, 3, 1, 14, 45))
print(utc)
# 2019-03-01 14:45:00+00:00

【讨论】:

感谢您的赞誉!但是我怎样才能得到 15:45 而不是 14:15 + 01:00?? @DaniLA - 你可以使用strftime 来设置你喜欢的输出格式。 怎么样?如果我这样做 madrid = dt.astimezone(madrid_tz) print(madrid) 我会得到 2019-03-01 14:45:00+01:00 如果我这样做 print(madrid.strftime ("%Y-%m-%d %H:%M") 我会得到 2019-03-01 14:45 @DaniLA - 你是如何初始化dt的?如果您按照答案中所示的方式进行操作,您将不会从print(madrid)获得 2019-03-01 14:45:00+01:00@ 我只是复制粘贴了您的“astimezone 示例”,但我的输出与您的不同。我的是 2019-03-01 14:45:00+01:00 和 2019-03-01 13:45:00+00:00 。我必须说我正在 windows 的 python3 中测试这个。如果我在我的 raspberrypi(也在 python3 中)执行您的 astimezone 示例,则在执行 madrid = dt.astimezone(madrid_tz) 时会收到类似 ValueError: astimezone() cannot be applied to a naive datetime 的错误。我很困惑......【参考方案2】:

让我们更清楚一点:这里是什么:

madrid = pytz.timezone('Europe/Madrid')

欧洲/马德里时区,即 UTC+1/+2。

naive_ts = datetime.strptime('2019-03-01 14:45', '%Y-%m-%d %H:%M')

没有任何特定时区的简单时间戳

madrid_ts = madrid.localize(naive_ts)

相同的时间戳,现在附加了欧洲/马德里时区,即 马德里 14:45 (UTC+1)

utc_ts = madrid_ts.astimezone(pytz.utc)

与马德里的 14:45 (UTC+1) UTC 的时间相同,因此,14:45 - 1 小时 → 13:45。 一切正常。如果马德里是 14:45,那么 UTC 就是 13:45,因为马德里比 UTC 早一小时。

datetime.now()

不管是什么……它与上述两个时间戳中的任何一个都无关,并且取决于您机器的默认时区以及您执行此代码时所在的当前时间。

【讨论】:

嗨@deceze,我认为错误在我的代码中,我刚刚编辑了我的问题以澄清我需要什么。 然后了解 naïve 日期时间(没有时区、模糊信息)和 aware 日期时间(有时区信息)之间的区别。您的 localize 将时区附加到天真的日期时间,然后您将其转换为不同的时区。如果你想从 UTC 转换到马德里,你需要反过来做。

以上是关于模块pytz:UTC减少而不是增加的主要内容,如果未能解决你的问题,请参考以下文章

python pytz检查时间是不是在悉尼/墨尔本时间而不是UTC之间

何时使用 datetime.utcnow() 或 datetime.now(tz=pytz.utc).replace(tzinfo=None)

Python & pytz:确定时区是不是支持 DST 以及 DST 和非 DST UTC 偏移量是多少

关于 Python 中的 pytz 模块和 time 模块

pytz.utc 和 dt.timezone.utc 有啥区别?

pytz UTC 转换