我们可以使用time.tzname
获取本地时区名称,但该名称与pytz.timezone
不兼容。
事实上,time.tzname
返回的名称含糊不清。此方法在我的系统中返回('CST', 'CST')
,但“CST”可以指示四个时区:
答案 0 :(得分:61)
tzlocal
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
即使在夏令时转换期间,当本地时间可能不明确时,它也能正常工作。
即使当地时区的utc偏移量不同, local_tz
也适用于过去的日期。基于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在1970-01-01上返回错误的 UTC + 4偏移量而不是正确的UTC + 3。
对于那些在2017年遇到这种情况的人来说, dateutil.tz.tzlocal()
仍然被打破。上面的例子现在有效,因为莫斯科当前的utf偏移量是UTC + 3(偶然等于1970年的utc偏移量)。为了演示错误,我们可以选择utc offset为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。
答案 1 :(得分:31)
使用tzlocal
function中的python-dateutil
package:
from dateutil.tz import tzlocal
localtimezone = tzlocal()
在内部,这是一个使用time.timezone
和time.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和受攻击的系统上,您需要从/etc/sysconfig/clock
读取它:
$ grep ZONE /etc/sysconfig/clock
ZONE="Europe/Oslo"
答案 2 :(得分:9)
解决这个问题的一种非常简单的方法:
import time
def localTzname():
offsetHour = time.timezone / 3600
return 'Etc/GMT%+d' % offsetHour
更新:@MartijnPieters说'这不适用于夏令时/夏令时。'那么这个版本怎么样?
import time
def localTzname():
if time.daylight:
offsetHour = time.altzone / 3600
else:
offsetHour = time.timezone / 3600
return 'Etc/GMT%+d' % offsetHour
答案 3 :(得分:4)
从Python 3.6开始,您只需运行templistx = []
templisty = []
templistz = []
for x in range(len(Bodies)):
planet = Bodies[x]
if planet == planetinit:
leftover_bin.append(0)
.
.
.
,系统时区就会添加到naive_datetime.astimezone()
对象中。
如果在不带参数的情况下(或在tz = None的情况下)被调用,则系统本地时区将作为目标时区。转换后的datetime实例的.tzinfo属性将设置为具有从操作系统获得的区域名称和偏移量的timezone实例。
https://docs.python.org/3/library/datetime.html#datetime.datetime.astimezone
示例:
naive_datetime
答案 4 :(得分:1)
我不知道这是否对您有用,但我认为它可以解决您更普遍的问题:
如果您的日期位于不明确的时区,例如CST
,simple-date(仅限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>
给出了我的语言环境的时区(不明确与否)。
答案 5 :(得分:-1)
import pytz
假设您在OBJ列表对象中有utc DateTime值列表。
tz=pytz.timezone('Asia/Singapore')
在URL下查找以获取相应的时区位置字符串参数 Is there a list of Pytz Timezones?
现在我们的tz是具有新加坡时间的对象
result=[]
for i in OBJ:
i=i+tz.utcoffset(i)
result.append(i)
结果列表对象具有您各自时区的DateTime值