如何获取与当前时区对应的tz_info对象?

37

Python(或者 pytz)中,有没有一个跨平台的函数可以返回与当前计算机所设置的时区对应的 tzinfo 对象?

不能依赖于环境变量,因为它们不是跨平台的。

8个回答

15
>>> import datetime
>>> today = datetime.datetime.now()
>>> insummer = datetime.datetime(2009,8,15,10,0,0)
>>> from pytz import reference
>>> localtime = reference.LocalTimezone()
>>> localtime.tzname(today)
'PST'
>>> localtime.tzname(insummer)
'PDT'
>>> 

6
pytz文档指出,pytz.reference应仅用于测试。 - jfs
该警告适用于reference.USTimeZone,它使用了美国夏令时2007年之前的规则。然而,在这里使用的reference.LocalTimezone探测了time.localtime的行为,其正确性是通过系统库维护的。reference.LocalTimezone在美国规则2007年更改前后都提供了正确的夏令时转换;我还没有测试其他国家的情况。 - rob
5
@rob: 错误。不要使用 LocalTimezone()pytz 提供了历史时区数据,而 time.timezonetime.altzone(由 LocalTimezone() 使用)是常量,最多反映最近的时区定义。本地时区在过去/未来可能有不同的 UTC 偏移量,例如,请在 2010-2015 年尝试使用 Europe/Moscow 时区,看看会发生什么。 - jfs
从我的理解来看,这只会影响处理历史时间或算术运算。对于我的目的,我只需要知道本地系统与UTC之间的偏移量,以便解析系统未来的时间戳(例如系统日志),然后立即转换为UTC。使用LocalTimezone()是否安全? - notbad.jpeg
@notbad.jpeg 不行。未来的UTC偏移量也可能会改变。 - jfs
pytz 已经存在于我的系统中,但是没有 pytz.reference(在 Mac OSX 10.6 上使用 Python 2.7.5)。 - Jason S

12
Python 3.7:最初的回答
import datetime

datetime.datetime.now().astimezone().tzinfo

11

tzlocal 模块 可以返回 pytz 时区,适用于 *nix 和 win32 系统:

from datetime import datetime
from tzlocal import get_localzone # $ pip install tzlocal

# get local timezone    
local_tz = get_localzone() 


print local_tz.localize(datetime(2012, 1, 15))
# -> 2012-01-15 00:00:00+04:00 # current utc offset
print local_tz.localize(datetime(2000, 1, 15))
# -> 2000-01-15 00:00:00+03:00 # past utc offset (note: +03 instead of +04)
print local_tz.localize(datetime(2000, 6, 15))
# -> 2000-06-15 00:00:00+04:00 # changes to utc offset due to DST

注意:它考虑了夏令时和非夏令时的UTC偏移更改。


5

1
time.timezone() 只返回与 UTC 的偏移量。我需要一个 tzinfo 对象,因此我可能会编写以下函数:
  1. 定义一个对应于 tzinfo 对象的类
  2. 实例化对象
  3. 返回它
- random guy
datetime文档中有一个例子,解释了如何使用tzinfo。 - SilentGhost
3
datetime.datetime.now() + datetime.timedelta(seconds=time.timezone) 这个操作很好地完成了任务。 - Baczek
2
@Baczek:time.timezone 不考虑夏令时。 - jfs

4

以下代码片段返回不同时区的时间,而不受服务器配置的时区影响。

# pip install pytz tzlocal

from tzlocal import get_localzone
from datetime import datetime
from pytz import timezone

local_tz = get_localzone()
local_datetime = datetime.now(local_tz)

zurich_tz = timezone('Europe/Zurich')
zurich_datetime = zurich_tz.normalize(local_datetime.astimezone(zurich_tz))

1
这里有没有不使用zurich_datetime = datetime.now(timezone('Europe/Zurich'))的原因?顺便说一下,在.astimezone()之后调用.normalize()是不必要的。 - jfs
如何在程序中编程获取“Europe/Zurich”时区字符串?我有很多机器,不知道它们的时区字符串是什么。 - JDPeckham

1

tzlocal() 可能无法处理过去的日期,例如 'Europe/Moscow' 时区在 2011 年之前具有不同的 UTC 偏移量(dateutil 失败,但 pytz 可以处理此类时区)。 - jfs

1

也许可以尝试:

import time

print time.tzname #或者 time.tzname[time.daylight]


将此与第一个答案进行比较,为什么是-1? - Rain Lee
1
[time.daylight] 表示当前时区是否具有夏令时。它并不表示当前是否正在执行夏令时。此外,time.tzname 不是 tzinfo 实例(它是一个字符串)。请参阅 如何获取系统时区设置并将其传递给 pytz.timezone? 了解即使您获得了正确的 tzname;也不意味着您会找到本地时区。请参阅 在 Python 中获取计算机的 UTC 偏移量,其中演示了几种获取当前 UTC 偏移量的方法。 - jfs

-1

我曾经也问过自己同样的问题,后来在[1]中找到了答案:

看一下8.1.7节:strftime的格式"%z"(小写,大写Z也返回时区,但不是4位数字格式,而是像[3]中的时区缩写那样)返回形式为"+/- 4DIGIT",这是电子邮件头部标准格式(参见RFC 2822第3.3节,参见[2],它废除了其他指定电子邮件头部时区的方式)。

因此,如果您想要以此格式显示您的时区,请使用:

time.strftime("%z")

[1] http://docs.python.org/2/library/datetime.html

[2] https://www.rfc-editor.org/rfc/rfc2822#section-3.3

[3] 时区缩写:http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations,仅供参考。


它不提供 tzinfo 对象。您可以通过以下方式获取本地时区的当前 UTC 偏移量(以秒为单位):-altzone if daylight and localtime().tm_isdst > 0 else -timezone(所有名称都来自 time 模块)。 - jfs

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