Python: 确定本地时区
我想把日志文件里的UTC时间戳和本地时间戳进行比较。当我创建本地的datetime
对象时,我会用类似下面的代码:
>>> local_time=datetime.datetime(2010, 4, 27, 12, 0, 0, 0,
tzinfo=pytz.timezone('Israel'))
我想找一个自动化的工具,可以把tzinfo=pytz.timezone('Israel')
替换成当前的本地时区。
有没有什么好主意?
19 个回答
42
要将日志文件中的UTC时间戳与本地时间戳进行比较。
找出本地时区的Olson时区名称有点困难,而且还要做到跨平台兼容。不过,幸运的是,你在进行比较时并不需要这个名称。
tzlocal
模块可以返回与本地时区对应的pytz时区:
from datetime import datetime
import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal
tz = get_localzone()
local_dt = tz.localize(datetime(2010, 4, 27, 12, 0, 0, 0), is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc) #NOTE: utc.normalize() is unnecessary here
与之前提到的其他解决方案不同,上面的代码避免了以下问题:
- 本地时间可能会产生歧义,也就是说,对于某些本地时间,精确比较可能会变得不可能。
- 同一个本地时区名称在过去的日期可能有不同的UTC偏移量。一些支持时区感知的日期时间对象的库(例如,
dateutil
)没有考虑到这一点。
注意:要从一个普通的日期时间对象获取一个时区感知的日期时间对象,你应该使用*:
local_dt = tz.localize(datetime(2010, 4, 27, 12, 0, 0, 0), is_dst=None)
而不是:
#XXX fails for some timezones
local_dt = datetime(2010, 4, 27, 12, 0, 0, 0, tzinfo=tz)
*is_dst=None
会在给定的本地时间存在歧义或不存在时强制抛出异常。
如果你确定所有本地时间戳都使用相同的(当前的)UTC偏移量,那么你可以仅使用标准库进行比较:
# convert a naive datetime object that represents time in local timezone to epoch time
timestamp1 = (datetime(2010, 4, 27, 12, 0, 0, 0) - datetime.fromtimestamp(0)).total_seconds()
# convert a naive datetime object that represents time in UTC to epoch time
timestamp2 = (datetime(2010, 4, 27, 9, 0) - datetime.utcfromtimestamp(0)).total_seconds()
timestamp1
和timestamp2
可以直接进行比较。
注意:
timestamp1
的公式只有在纪元时的UTC偏移量(datetime.fromtimestamp(0)
)与现在相同的情况下才有效。fromtimestamp()
会在当前本地时区创建一个普通的日期时间对象。utcfromtimestamp()
会在UTC创建一个普通的日期时间对象。
200
在Python 3.x中,可以这样找出本地时区:
>>> import datetime
>>> print(datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo)
AEST
这是对datetime
模块的一个比较复杂的用法,可以查看这里的代码。
如果你使用的是Python 3.6之前的版本,你需要这样做:
>>> import datetime
>>> print(datetime.datetime.now(datetime.timezone(datetime.timedelta(0))).astimezone().tzinfo)
AEST