使用Python从时区名称获取UTC偏移量

107

如何在Python中从时区名称获取UTC偏移量?

例如:我有Asia/Jerusalem,我想得到+0200


16
在Python 3.9中,您可以使用datetime.datetime.now(zoneinfo.ZoneInfo('Asia/Jerusalem')).utcoffset(),无需使用任何第三方库。 - FObersteiner
5个回答

147

由于夏令时(Daylight Saving Time)的影响,结果取决于一年中的时间:

import datetime, pytz

datetime.datetime.now(pytz.timezone('Asia/Jerusalem')).strftime('%z')

# returns '+0300' (because 'now' they have DST)


pytz.timezone('Asia/Jerusalem').localize(datetime.datetime(2011,1,1)).strftime('%z')

# returns '+0200' (because in January they didn't have DST)

pytz.timezone("Etc/GMT-5").localize(datetime.datetime(2011, 1, 1)).strftime("%z") 返回的是 "+0500",而不是 "-0500"。 - 404usernamenotfound
@404usernamenotfound我认为在编程上下文中,GMT-5实际上意味着+0500,并且转换成人类语言后表示"GMT+5"。令人困惑吗?是的。 - Janne Paalijarvi
@JannePaalijarvi 不,我的列表中正数的命名方式是Etc/GMT+n。还有负数的时区Etc/GMT-n。我让它正常工作了,但没有使用pytz。 - 404usernamenotfound
Etc/GMT-5 => +0500 是有效的: root@am335x-evm:~# timedatectl 本地时间:2023年08月18日 星期五 10:46:24 +05 世界标准时间:2023年08月18日 星期五 05:46:24 UTC RTC 时间:2023年08月18日 星期五 05:46:25 时区:Etc/GMT-5 (+05, +0500) 系统时钟已同步:是 NTP 服务:活动中 RTC 在本地时区:否 - Janne Paalijarvi

84

你尝试过使用 pytz 项目和 utcoffset 方法吗?

例如:

>>> import datetime
>>> import pytz
>>> pacific_now = datetime.datetime.now(pytz.timezone('US/Pacific'))
>>> pacific_now.utcoffset().total_seconds()/60/60
-7.0

2
顺便提一下,pytz的Ubuntu软件包名为python-tz。 - Randall Cook
2
我不敢给他点踩,但是据我所知,utcoffset是datetime对象上的方法,因此它不会根据时区名称提供这个功能。 - Tom
1
@Tom:不过也可以在 tzinfo 对象上使用。请参见 http://pytz.sourceforge.net/#tzinfo-api - Jon Skeet
1
@jon-skeet 谢谢,我漏了那个。我们现在正式要“打牌”了吗? - Tom
4
请注意,如果服务器使用的时区与给定的时区不同,则在夏令时切换期间会产生不正确的结果。传递给timezone.utcoffset()的日期时间假定为该时区的本地时间,如果传递了夏令时开始或结束的小时,则会失败。更好的方法是使用datetime.datetime.utcnow().replace(tzinfo=pytz.utc).astimezone(pytz.timezone('US/Pacific')).utcoffset().total_seconds() / 60 / 60 - Nathan Villaescusa
显示剩余5条评论

2

以下是@Jon Skeet 答案中的另一种观点,假设您已经有datetime.datetime对象,例如day = datetime.datetime(2021, 4, 24)

import pytz
tz = pytz.timezone("Asia/Kolkata")

import datetime
day = datetime.datetime(2021, 4, 24)

offset = tz.utcoffset(day)/3600

2

在将python datetime对象转换为UTC时间戳时,我遇到了类似的问题。我的datetime对象没有时区(非常天真),因此astimezone无法工作。

为了缓解这个问题,我让我的datetime对象有了时区意识,然后使用了上述方法。

import pytz
system_tz = pytz.timezone(constants.TIME_ZONE)
localized_time = system_tz.localize(time_of_meeting)
fmt = "%Y%m%dT%H%M%S" + 'Z'
return localized_time.astimezone(pytz.utc).strftime(fmt)

在这里,constants.TIME_ZONE 是我持久化对象的默认时区。

希望这能帮助那些试图将Python日期时间对象转换为UTC的人。一旦转换完成,可以按任意方式格式化。


0

以另一种方式将UTC偏移量转换为整数:

import datetime
import pytz
from tzwhere import tzwhere

tzwhere = tzwhere.tzwhere()
timezone = pytz.timezone('Asia/Jerusalem')
offSet_str = str(timezone.utcoffset(datetime.datetime.now()))
if offSet_str[0] != '-':
    offSet = int(offSet_str[0])
else:
    offSet = int(offSet_str[8] + offSet_str[9]) - 24

print(offSet)

Jon Skeet有一种更快的方法


1
请注意,UTC偏移量并不总是整数。一些时区具有45分钟的偏移量。唉... - Eric Duminil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接