我想将日志文件中的UTC时间戳与本地时间戳进行比较。在创建本地datetime
对象时,我使用类似:
>>> local_time=datetime.datetime(2010, 4, 27, 12, 0, 0, 0,
tzinfo=pytz.timezone('Israel'))
我想找到一个自动工具,将tzinfo=pytz.timezone('Israel')
替换为当前的本地时区。
有什么想法吗?
答案 0 :(得分:53)
在Python 3.x中,本地时区可能会像这样:
import datetime
LOCAL_TIMEZONE = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
datetime
' code 使用起来很棘手。
答案 1 :(得分:30)
答案 2 :(得分:27)
将日志文件中的UTC时间戳与本地时间戳进行比较。
便携式hard to find out Olson TZ name for a local timezone。幸运的是,您不需要它来执行比较。
tzlocal
module返回与本地时区对应的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
与目前为止提供的其他解决方案不同,上述代码避免了以下问题:
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偏移量,那么您可以仅使用stdlib执行比较:
# 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
公式仅在时代(datetime.fromtimestamp(0)
)的UTC偏移与现在相同时才有效fromtimestamp()
在当前本地时区创建一个天真的日期时间对象utcfromtimestamp()
以UTC格式创建一个天真的日期时间对象。答案 3 :(得分:12)
我对自己问了同样的问题,我在1中找到答案:
请参阅第8.1.7节:格式“%z”(小写,Z大写也返回时区,但不是4位格式,但是以时区缩写的形式,如[ strftime的3])返回电子邮件标题中标准的“+/- 4DIGIT”形式(参见RFC 2822的3.3节,参见[2],它废弃了指定电子邮件标题时区的其他方法)。
因此,如果您想要这种格式的时区,请使用:
time.strftime("%z")
[1] http://docs.python.org/2/library/datetime.html
[2] http://tools.ietf.org/html/rfc2822#section-3.3
[3]时区缩写:http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations,仅供参考。
答案 4 :(得分:6)
首先获取pytz和tzlocal模块
pip install pytz tzlocal
然后
from tzlocal import get_localzone
local = get_localzone()
那么你可以做像
这样的事情from datetime import datetime
print(datetime.now(local))
答案 5 :(得分:5)
使用标准库,以下内容似乎适用于3.7 +:
from datetime import timedelta
from datetime import timezone
import time
def currenttz():
if time.daylight:
return timezone(timedelta(seconds=-time.altzone),time.tzname[1])
else:
return timezone(timedelta(seconds=-time.timezone),time.tzname[0])
答案 6 :(得分:4)
这是一种仅使用标准库获取本地时区的方法(仅适用于* nix环境):
>>> '/'.join(os.path.realpath('/etc/localtime').split('/')[-2:])
'Australia/Sydney'
您可以使用此功能创建pytz
时区:
>>> import pytz
>>> my_tz_name = '/'.join(os.path.realpath('/etc/localtime').split('/')[-2:])
>>> my_tz = pytz.timezone(my_tz_name)
>>> my_tz
<DstTzInfo 'Australia/Sydney' LMT+10:05:00 STD>
...然后您可以将其应用于datetime
:
>>> import datetime
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2014, 9, 3, 9, 23, 24, 139059)
>>> now.replace(tzinfo=my_tz)
>>> now
datetime.datetime(2014, 9, 3, 9, 23, 24, 139059, tzinfo=<DstTzInfo 'Australia/Sydney' LMT+10:05:00 STD>)
答案 7 :(得分:3)
基于J. F. Sebastian's answer,您可以使用标准库执行此操作:
import time, datetime
local_timezone = datetime.timezone(datetime.timedelta(seconds=-time.timezone))
在3.4中测试,应该在3.4 +上工作
答案 8 :(得分:3)
这是@ vbem解决方案的一个稍微简洁的版本:
from datetime import datetime as dt
dt.utcnow().astimezone().tzinfo
唯一的实质性区别是我将datetime.datetime.now(datetime.timezone.utc)
替换为datetime.datetime.utcnow()
。为简洁起见,我还将datetime.datetime
别名为dt
。
出于我的目的,我希望以秒为单位的UTC偏移量。这是看起来像:
dt.utcnow().astimezone().utcoffset().total_seconds()
答案 9 :(得分:2)
避免使用非标准模块(似乎缺少日期时间模块的方法):
from datetime import datetime
utcOffset_min = int(round((datetime.now() - datetime.utcnow()).total_seconds())) / 60 # round for taking time twice
utcOffset_h = utcOffset_min / 60
assert(utcOffset_min == utcOffset_h * 60) # we do not handle 1/2 h timezone offsets
print 'Local time offset is %i h to UTC.' % (utcOffset_h)
答案 10 :(得分:2)
根据Thoku上面的答案,这里有一个答案,将时区解析到最近的半小时(这与某些时区有关,例如南澳大利亚州):
from datetime import datetime
round((round((datetime.now()-datetime.utcnow()).total_seconds())/1800)/2)
答案 11 :(得分:1)
对于简单的事情,可以使用以下tzinfo
实现,它会查询操作系统的时区偏移量:
import datetime
import time
class LocalTZ(datetime.tzinfo):
_unixEpochOrdinal = datetime.datetime.utcfromtimestamp(0).toordinal()
def dst(self, dt):
return datetime.timedelta(0)
def utcoffset(self, dt):
t = (dt.toordinal() - self._unixEpochOrdinal)*86400 + dt.hour*3600 + dt.minute*60 + dt.second + time.timezone
utc = datetime.datetime(*time.gmtime(t)[:6])
local = datetime.datetime(*time.localtime(t)[:6])
return local - utc
print datetime.datetime.now(LocalTZ())
print datetime.datetime(2010, 4, 27, 12, 0, 0, tzinfo=LocalTZ())
# If you're in the EU, the following datetimes are right on the DST change.
print datetime.datetime(2013, 3, 31, 0, 59, 59, tzinfo=LocalTZ())
print datetime.datetime(2013, 3, 31, 1, 0, 0, tzinfo=LocalTZ())
print datetime.datetime(2013, 3, 31, 1, 59, 59, tzinfo=LocalTZ())
# The following datetime is invalid, as the clock moves directly from
# 01:59:59 standard time to 03:00:00 daylight savings time.
print datetime.datetime(2013, 3, 31, 2, 0, 0, tzinfo=LocalTZ())
print datetime.datetime(2013, 10, 27, 0, 59, 59, tzinfo=LocalTZ())
print datetime.datetime(2013, 10, 27, 1, 0, 0, tzinfo=LocalTZ())
print datetime.datetime(2013, 10, 27, 1, 59, 59, tzinfo=LocalTZ())
# The following datetime is ambigous, as 02:00 can be either DST or standard
# time. (It is interpreted as standard time.)
print datetime.datetime(2013, 10, 27, 2, 0, 0, tzinfo=LocalTZ())
答案 12 :(得分:1)
我想将日志文件中的UTC时间戳与本地时间戳进行比较
如果这是您的意图,那么我不必担心指定特定的tzinfo参数或任何其他外部库。从Python 3.5开始,内置的datetime模块是自动创建UTC和本地时间戳的全部功能。
import datetime
f = "%a %b %d %H:%M:%S %Z %Y" # Full format with timezone
# tzinfo=None
cdatetime = datetime.datetime(2010, 4, 27, 12, 0, 0, 0) # 1. Your example from log
cdatetime = datetime.datetime.now() # 2. Basic date creation (default: local time)
print(cdatetime.strftime(f)) # no timezone printed
# Tue Apr 27 12:00:00 2010
utctimestamp = cdatetime.astimezone(tz=datetime.timezone.utc) # 1. convert to UTC
utctimestamp = datetime.datetime.now(tz=datetime.timezone.utc) # 2. create in UTC
print(utctimestamp.strftime(f))
# Tue Apr 27 17:00:00 UTC 2010
localtimestamp = cdatetime.astimezone() # 1. convert to local [default]
localtimestamp = datetime.datetime.now().astimezone() # 2. create with local timezone
print(localtimestamp.strftime(f))
# Tue Apr 27 12:00:00 CDT 2010
datetime.strftime()的'%Z'参数将时区首字母缩写打印到时间戳中,以供人类阅读。
答案 13 :(得分:1)
您可能会对pendulum
感到满意>>> pendulum.datetime(2015, 2, 5, tz='local').timezone.name
'Israel'
Pendulum具有精心设计的用于处理日期的API。一切都支持TZ。
答案 14 :(得分:1)
now_dt = datetime.datetime.now()
utc_now = datetime.datetime.utcnow()
now_ts, utc_ts = map(time.mktime, map(datetime.datetime.timetuple, (now_dt, utc_now)))
offset = int((now_ts - utc_ts) / 3600)
希望这会对您有所帮助。
答案 15 :(得分:0)
我还一直在寻找一种简单的方法来读取本地主机配置,并基于该配置获取时区感知的local_time。从python 3.6开始,最简单的方法是使用dateutil.tz,它将读取/etc/localtime
并帮助获取时区感知的datetime对象。
这里有更多信息:https://dateutil.readthedocs.io/en/stable/tz.html
完成您要寻找的实现的方法如下:
from datetime import datetime
from dateutil import tz
local_time = datetime.now(tz.gettz())
这将为您提供以下local_time:
2019-10-18 13:41:06.624536-05:00
我在研究此主题时使用的其他资源: Paul Ganssle有关时区的演示文稿: https://www.youtube.com/watch?v=l4UCKCo9FWY
pytz:西方最快的步枪 https://blog.ganssle.io/articles/2018/03/pytz-fastest-footgun.html答案 16 :(得分:0)
首先,请注意该问题表示感知日期时间对象的初始化不正确:
>>> local_time=datetime.datetime(2010, 4, 27, 12, 0, 0, 0,
... tzinfo=pytz.timezone('Israel'))
创建一个无效的实例。通过计算结果对象的UTC偏移量可以看出问题:
>>> print(local_time.utcoffset())
2:21:00
(注意结果是一小时的奇数。)
要使用pytz正确初始化感知日期时间,应使用localize()
方法,如下所示:
>>> local_time=pytz.timezone('Israel').localize(datetime.datetime(2010, 4, 27, 12))
>>> print(local_time.utcoffset())
3:00:00
现在,如果你需要一个本地pytz时区作为新的tzinfo,你应该使用tzlocal包,正如其他人所解释的那样,但是如果你需要的只是一个具有正确本地时区偏移和缩写的实例,那么就用Python 3.3进行tarting ,您可以调用不带参数的astimezone()
方法将知道的datetime
实例转换为您当地的时区:
>>> local_time.astimezone().strftime('%Y-%m-%d %H:%M %Z %z')
'2010-04-27 05:00 EDT -0400'
答案 17 :(得分:-1)
代码示例如下。最后一个字符串,适用于文件名。
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> str(datetime.now(tzlocal()))
'2015-04-01 11:19:47.980883-07:00'
>>> str(datetime.now(tzlocal())).replace(' ','-').replace(':','').replace('.','-')
'2015-04-01-111947-981879-0700'
>>>