【发布时间】:2010-11-09 19:26:33
【问题描述】:
我想从 Python 获取系统的默认时区 (PST)。最好的方法是什么?我想避免分叉另一个进程。
【问题讨论】:
我想从 Python 获取系统的默认时区 (PST)。最好的方法是什么?我想避免分叉另一个进程。
【问题讨论】:
这应该可行:
import time
time.tzname
time.tzname 返回两个字符串的元组:第一个是本地非 DST 时区的名称,第二个是本地 DST 时区的名称。
示例返回:('MST', 'MDT')
【讨论】:
time.tzname[time.daylight] 获取当前时区的名称,考虑夏令时。
time.tzname may return a wrong value 如果本地时区过去有不同的缩写(Python 使用 1 月、7 月的值或当前 (import/tzset() time) 值)。 tzlocal 模块可用于获取给定日期的正确 tzname。
像 ThomasH 的回答一样给出 UTC 偏移量,但考虑到夏令时。
>>> import time
>>> offset = time.timezone if (time.localtime().tm_isdst == 0) else time.altzone
>>> offset / 60 / 60 * -1
-9
time.timezone 或 time.altzone 的值以 UTC 以西的秒数为单位(UTC 以东的区域为负值)。这与我们实际想要的相反,因此 * -1。
如果夏令时当前没有生效,time.localtime().tm_isdst 将为零(尽管如果某个地区最近更改了夏令时法,这可能不正确)。
编辑:marr75 是正确的,我已经相应地编辑了答案。
【讨论】:
tm_isdst 将是 -1,在这种情况下,当前代码将默认为 altzone。对于不使用 DST 的区域,此值永远不会正确,因此 timezone 可能应该是后备。 (我不确定-1 是否真的可以从localtime 输出)
【讨论】:
%Z 产生 TZ 首字母缩写词,例如。 CET,而%z 产生偏移量,例如。 +0100
我发现这很好用:
import datetime
tz_string = datetime.datetime.now(datetime.timezone.utc).astimezone().tzname()
对我来说,这可以区分夏令时与否。
【讨论】:
计算偏移量的代码sn-ps不正确,见http://bugs.python.org/issue7229。
正确的处理方法是:
def local_time_offset(t=None):
"""Return offset of local zone from GMT, either at present or at time t."""
# python2.3 localtime() can't take None
if t is None:
t = time.time()
if time.localtime(t).tm_isdst and time.daylight:
return -time.altzone
else:
return -time.timezone
这很可能不是 OP 提出的确切问题,但页面上有两个不正确的 sn-ps 并且时间错误很难追踪和修复。
【讨论】:
tm_isdst;你不需要检查daylight 2. all altzone, timezone-based solution may fail in some edge cases
对于 Python 3.6+,这可以通过以下代码轻松实现:
import datetime
local_timezone = datetime.datetime.utcnow().astimezone().tzinfo
print(local_timezone)
但是对于 Python astimezone() 不起作用。所以我们必须以稍微不同的方式来做。
所以对于 Python 3.x,
import datetime
local_timezone = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
print(local_timezone)
样本输出:
在荷兰服务器(Python 3.6.9)上:
CEST
在孟加拉国服务器(Python 3.8.2)上:
+06
更多细节可以在这个thread找到。
【讨论】:
从 UTC 获取偏移为 timedelta:
from datetime import datetime, timezone
now = datetime.now()
now.replace(tzinfo=timezone.utc) - now.astimezone(timezone.utc)
或者像这样(更晦涩但也有效):
datetime.now(timezone.utc).astimezone().tzinfo.utcoffset(None)
两种解决方案的结果相同。例如:datetime.timedelta(seconds=7200)
【讨论】:
要以datetime.tzinfo 对象的形式获取时区信息,请使用dateutil.tz.tzlocal():
from dateutil import tz
myTimeZone = tz.tzlocal()
这个对象可以用在datetime.datetime.now()的tz参数中:
from datetime import datetime
from dateutil import tz
localisedDatetime = datetime.now(tz = tz.tzlocal())
或datetime对象的tz参数通过datetime.datetime.astimezone():
from datetime import datetime
from dateutil import tz
unlocalisedDatetime = datetime.now()
localisedDatetime = unlocalisedDatetime.astimezone(tz = tz.tzlocal())
【讨论】: