如何获取系统时区设置并将其传递给pytz.timezone?

2024-09-29 21:37:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我们可以使用time.tzname获取本地时区名称,但该名称与pytz.timezone不兼容。

实际上,time.tzname返回的名称不明确。此方法返回系统中的('CST', 'CST'),但“CST”可以指示四个时区:

  • 中部时区(北美)-在北美中部时区观测
  • 中国标准时间
  • 中原标准时间-台湾现在很少使用“中原标准时间”这个词
  • 澳大利亚中部标准时间(ACST)

Tags: 方法名称标准time系统时间timezonepytz
3条回答

^{} module返回与本地时区对应的pytz tzinfo对象:

import time
from datetime import datetime

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

# get local timezone    
local_tz = get_localzone() 

# test it
# utc_now, now = datetime.utcnow(), datetime.now()
ts = time.time()
utc_now, now = datetime.utcfromtimestamp(ts), datetime.fromtimestamp(ts)

local_now = utc_now.replace(tzinfo=pytz.utc).astimezone(local_tz) # utc -> local
assert local_now.replace(tzinfo=None) == now

即使在夏令时转换期间,当本地时间可能不明确时,它也能工作。

local_tz也适用于过去的日期,即使当时本地时区的utc偏移量不同。^基于{}的解决方案在这种情况下失败,例如在欧洲/莫斯科时区(2013年起的示例):

>>> import os, time
>>> os.environ['TZ'] = 'Europe/Moscow'
>>> time.tzset()
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> from tzlocal import get_localzone
>>> dateutil_tz = tzlocal()
>>> tzlocal_tz = get_localzone()
>>> datetime.fromtimestamp(0, dateutil_tz)                              
datetime.datetime(1970, 1, 1, 4, 0, tzinfo=tzlocal())
>>> datetime.fromtimestamp(0, tzlocal_tz)
datetime.datetime(1970, 1, 1, 3, 0, tzinfo=<DstTzInfo 'Europe/Moscow' MSK+3:00:00 STD>)

dateutil返回错误的UTC+4偏移量,而不是1970-01-01的正确的UTC+3。

对于那些在2017年遇到这种情况的人来说,{}仍然是破碎的。上面的例子现在可以工作了,因为当前的utf偏移量在莫斯科是UTC+3(意外地等于1970年的UTC偏移量)。为了演示错误,我们可以选择utc偏移量为utc+4的日期:

>>> import os, time
>>> os.environ['TZ'] = 'Europe/Moscow'
>>> time.tzset()
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> from tzlocal import get_localzone
>>> dateutil_tz = tzlocal()
>>> tzlocal_tz = get_localzone()
>>> ts = datetime(2014, 6,1).timestamp() # get date in 2014 when gmtoff=14400 in Moscow
>>> datetime.fromtimestamp(ts, dateutil_tz)
datetime.datetime(2014, 5, 31, 23, 0, tzinfo=tzlocal())
>>> datetime.fromtimestamp(ts, tzlocal_tz)
datetime.datetime(2014, 6, 1, 0, 0, tzinfo=<DstTzInfo 'Europe/Moscow' MSK+4:00:00 STD>)

dateutil在2014-06-01返回错误的UTC+3偏移量,而不是正确的UTC+4。

解决这个问题的一个非常简单的方法是:

import time

def localTzname():
    offsetHour = time.timezone / 3600
    return 'Etc/GMT%+d' % offsetHour

更新:@MartijnPieters说“这不适用于DST/summertime”。那么这个版本呢?

import time

def localTzname():
    if time.daylight:
        offsetHour = time.altzone / 3600
    else:
        offsetHour = time.timezone / 3600
    return 'Etc/GMT%+d' % offsetHour

使用^{} package中的^{} function

from dateutil.tz import tzlocal

localtimezone = tzlocal()

在内部,这是一个使用time.timezonetime.altzone(基于time.daylight进行切换)的类,但从中创建合适的时区对象。

您使用这个来代替一个pytz时区的

另一种方法是从操作系统读取当前配置的时区,但这与操作系统之间的差别很大。在Mac OS X上,您需要读取systemsetup -gettimezone的输出:

$ systemsetup -gettimezone
Time Zone: Europe/Copenhagen

在Debian和Ubuntu系统上,您可以读取/etc/timezone

$ cat /etc/timezone
Europe/Oslo

在RedHat和direved系统上,您需要从/etc/sysconfig/clock中读取它:

$ grep ZONE /etc/sysconfig/clock
ZONE="Europe/Oslo"

相关问题 更多 >

    热门问题