如何获取系统时区设置并将其传递给Pytz.TimeZone



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

实际上,time.tzname返回的名称模棱两可。此方法在我的系统中返回('CST', 'CST'),但是" CST"可以指示四个时区:

  • 中央时区(北美) - 在北美的中央时区观察
  • 中国标准时间
  • chungyuan标准时间 - 台湾很少使用" chungyuan标准时间"一词
  • 澳大利亚中央标准时间(ACST)

tzlocal模块返回与本地时区相对应的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抵消了UTC。在这种情况下,基于dateutil.tz.tzlocal()的解决方案失败了,例如在欧洲/莫斯科时区(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年碰到的人 dateutil.tz.tzlocal()仍被打破。上面的示例现在起作用,因为当前的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返回错误 UTC 3偏移量,而不是2014-06-01的正确UTC 4。

由于Python 3.6,您可以简单地运行naive_datetime.astimezone(),并且系统时区将添加到naive_datetime对象中。

如果没有参数(或使用TZ = none)调用,则假定系统局部时区为目标时区。转换后的DateTime实例的.tzinfo属性将设置为具有从OS的区域名称和偏移的时区实例。

https://docs.python.org/3/library/dateTime.html#datement.datetime.astimezone

示例:

>>> import datetime
>>> datetime.datetime.now().astimezone().isoformat(timespec='minutes')
'2018-10-02T13:09+03:00'

使用python-dateutil软件包的tzlocal函数:

from dateutil.tz import tzlocal
localtimezone = tzlocal()

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

您使用pytz时区的此

替代方法是从操作系统读取当前配置的时区,但从OS到OS,这有很大不同。在Mac OS X上,您需要读取systemsetup -gettimezone的输出:

$ systemsetup -gettimezone
Time Zone: Europe/Copenhagen

在Debian和Ubuntu Systems上,您可以阅读/etc/timezone

$ cat /etc/timezone
Europe/Oslo

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

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

解决此问题的一种非常简单的方法:

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

update :@martijnpieters说:"这与DST/Summertime无法使用。"那这个版本呢?

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

我不知道这对您是否有用,但我认为它可以解决您更一般的问题:

如果您有一个模棱两可的时区的日期,例如CST,简单日期(仅python 3.2 ,对不起)可以自动搜索,并允许您做一些喜欢某些国家/地区的事情。

例如:

>>> SimpleDate('2013-07-04 18:53 CST')
Traceback [...
simpledate.AmbiguousTimezone: 3 distinct timezones found: <DstTzInfo 'Australia/Broken_Hill' CST+9:30:00 STD>; <DstTzInfo 'America/Regina' LMT-1 day, 17:01:00 STD>; <DstTzInfo 'Asia/Harbin' LMT+8:27:00 STD> (timezones=('CST',), datetime=datetime.datetime(2013, 7, 4, 18, 53), is_dst=False, country=None, unsafe=False)
>>> SimpleDate('2013-07-04 18:53 CST', country='CN')
SimpleDate('2013-07-04 18:53 CST')
>>> SimpleDate('2013-07-04 18:53 CST', country='CN').utc
SimpleDate('2013-07-04 10:53 UTC', tz='UTC')

请注意,通过指定一个国家,您如何减少可能的值的范围,以允许转换为UTC。

它是通过对Pytz中的时区进行搜索来实现的:

>>> SimpleDate('2013-07-04 18:53 CST', country='CN', debug=True)
...
PyTzFactory: Have country code CN
PyTzFactory: Country code CN has 5 timezones
PyTzFactory: Expanded country codes to 5 timezones
PyTzFactory: Expanding ('CST',)
PyTzFactory: Name lookup failed for CST
PyTzFactory: Found CST using Asia/Shanghai
PyTzFactory: Found CST using Asia/Harbin
PyTzFactory: Found CST using Asia/Chongqing
PyTzFactory: Found CST using Asia/Urumqi
PyTzFactory: Found CST using Asia/Kashgar
PyTzFactory: Expanded timezone to 5 timezones
PyTzFactory: New offset 8:00:00 for Asia/Shanghai
PyTzFactory: Known offset 8:00:00 for Asia/Harbin
PyTzFactory: Known offset 8:00:00 for Asia/Chongqing
PyTzFactory: Known offset 8:00:00 for Asia/Urumqi
PyTzFactory: Known offset 8:00:00 for Asia/Kashgar
PyTzFactory: Have 1 distinct timezone(s)
PyTzFactory: Found Asia/Shanghai
...
SimpleDate('2013-07-04 18:53 CST')

最后,要直接回答问题,它也包裹了tzlocal,如这里的另一个答案所述,如果您不给时区不提供时区,则会自动执行您期望的事情。例如,我住在智利,所以

>>> SimpleDate()
SimpleDate('2013-07-04 19:21:25.757222 CLT', tz='America/Santiago')
>>> SimpleDate().tzinfo
<DstTzInfo 'America/Santiago' CLT-1 day, 20:00:00 STD>

给出了我所在的时区(是否模棱两可)。

import pytz

说您在OBJ列表对象中有UTC DateTime值列表。

tz=pytz.timezone('Asia/Singapore')

在下面找到各个时区位置字符串参数有PYTZ时区列表吗?

现在我们的TZ是具有新加坡时间的对象

result=[]
for i in OBJ:
    i=i+tz.utcoffset(i)
    result.append(i)

结果列表对象具有您相应时区的日期值

最新更新