【问题标题】:Converting local times to UTC for different countries将不同国家的当地时间转换为 UTC
【发布时间】:2022-01-05 14:32:42
【问题描述】:

我想将不同国家的当地时间转换为 UTC 时间。我正在尝试用这种方式做到这一点:

tz = pytz.timezone('Europe/Berlin')
x=tz.normalize(tz.localize(datetime.now())).astimezone(pytz.utc)

它给了我正确的结果。但是当我尝试为 Europe/Lisbon 这样做时,我得到了错误的结果。这可能是一个问题还是我做错了什么?两个时区之间没有差异,但它给了我 3 小时的差异,如下所示。

提前致谢。

【问题讨论】:

  • 您的本地机器时区是Europe/Lisbon 对吧?
  • 可以用code格式的文本替换图片吗?将代码本身扩展为完整的 minimal reproducible example,包含所有导入和固定的参考时间,也将提高此问题的可重用性。
  • @PSSolanki 实际上没有,我有来自里斯本的数据,我想将其转换为 UTC。我的时区是欧洲/伊斯坦布尔。
  • 你从哪里得到这些数据?为什么您使用datetime.now() 进行测试,而您应该使用示例日期时间,对吧?
  • 我已经搜索过,但找不到其他方法。我猜 astimezone 函数将其转换为 utc。

标签: python python-3.x datetime time pytz


【解决方案1】:

我不确定你为什么会弄错时间。我试过这种方法,我得到了正确的方法。只是我将当前时间冻结到一个变量,并用它来检查作为调试。 里斯本的时间为 UTC - 没有区别 附言虽然我在本地时区,因此您可能会看到我的时间与您的时间不同,但差异似乎是正确的。柏林比世界标准时间早 1 小时,而里斯本与世界标准时间相同

import pytz
from datetime import datetime

tz = pytz.timezone('Europe/Berlin')
tb = tz.localize(datetime.now())
print(f"Berlin Time:   {tb}")
x=tz.normalize(tb).astimezone(pytz.utc)
print(f"Berin to UTC:   {x}")

tz2 = pytz.timezone('Europe/Lisbon')
tl = tz2.localize(datetime.now())
print(f"Lisbon Time:   {tl}")
y=tz2.normalize(tl).astimezone(pytz.utc)
print(f"Lisbon to UTC:   {tl}")

结果如下:

Berlin Time:   2022-01-05 20:19:28.576504+01:00
Berin to UTC:   2022-01-05 19:19:28.576504+00:00
Lisbon Time:   2022-01-05 20:19:28.578506+00:00
Lisbon to UTC:   2022-01-05 20:19:28.578506+00:00

Process finished with exit code 0

【讨论】:

  • 请注意,您不需要致电 normalize。 astimezone 应该足够了。
  • 这里也不需要本地化;直接datetime.now(pytz.timezone('Europe/Berlin'))
  • @MrFuppes 实际使用localize 优于直接在构造函数中指定时区。原因是有些时区在这样做时会有不正确的值。 Asia/Kolkata 就是一个例子。
  • @PSSolanki 实际上,如果日期时间对象已经存在,您必须使用localize(带有outdated pytz) - 除非您使用datetime.now 构造函数或转换为 astimezone 或 tzinfo 是 UTC。直接在now 中设置 tz 对我来说似乎更具可读性。
  • @MrFuppes 它确实是可读的,但它为某些时区提供了不正确的值。我注意到 Asia/Kolkata 使用 datetime.datetime.now 并在构造函数中指定 tzinfo 的这种行为。这就像2个月前。我还记得在 pytz 邮件列表上看到很多关于这个主题的票。这与某些时区如何改变它们的偏移量有关。例如,Asia/Kolkata 的偏移量与现在不同,这会导致值不正确。
【解决方案2】:

这应该适用于将您的本地时间转换为可感知时区的 UTC datetime 对象

我猜您可能对 DST 有疑问。对localize() 的调用要求您指定时区是否服务于夏令时。它默认为 False。

其他可能性只是您使用的是当地时间(考虑到您自己不在里斯本),并且由于您将该时间本地化为里斯本时区,这当然会导致时间不正确。

import pytz
import datetime


timezone = pytz.timezone('Europe/Lisbon')

original_time = datetime.datetime(2021, 10, 15, 13, 15)  # change this to sample datetime to test different values

local_timezone_datetime = timezone.localize(original_time, False)  # change False to True if DST is enabled on the timezone

converted_datetime = local_timezone_datetime.astimezone(pytz.utc)

print(converted_datetime)

让我知道您是否需要一个函数来帮助您确定某个时区是否提供 DST。

【讨论】:

  • 我认为 DST True/False 仅适用于 DST 转换期间的模棱两可的时间,您不能为 tz“启用”或“禁用”DST; DST 开/关由 tz 规则定义决定。
  • @MrFuppes 我不确定你所说的那句话是什么意思。 DST开/关是一种现象。介意详细说明吗?
  • 抱歉,评论似乎有点断章取义 ;-) 它指的是 .localize(original_time, False) 中 DST 关键字的使用 - 我的意思是,如果日期/时间明确,则 kwarg 无效,即,从时区规则可以清楚地看出 DST 在那个时间点是否处于活动状态。关键字设置仅对 (UTC) 日期/时间有影响,该日期/时间可能指给定时区中的多个挂钟时间。
  • 有趣。我使用一个函数来确定一个时区是否有 DST,并将该值传递给 kwarg。
  • 你真的不应该这样做。这就是时区规则的用途,像 pytz 这样的库应该正确使用这些规则。
猜你喜欢
  • 2021-03-20
  • 2020-04-28
  • 2016-02-22
  • 2015-11-22
  • 1970-01-01
  • 2018-11-12
  • 2015-09-26
  • 1970-01-01
  • 2015-06-12
相关资源
最近更新 更多