time.strptime
解析字符串,并将元组的前六个元素传递给datetime构造函数,例如:datetime.datetime(*time.strptime("2007-03-04T21:08:12", "%Y-%m-%dT%H:%M:%S")[:6])
我还没有找到更好的方法来做这件事。有吗?
time.strptime
解析字符串,并将元组的前六个元素传递给datetime构造函数,例如:datetime.datetime(*time.strptime("2007-03-04T21:08:12", "%Y-%m-%dT%H:%M:%S")[:6])
我还没有找到更好的方法来做这件事。有吗?
我更喜欢使用dateutil库来处理时区和日期解析。如果你碰到像这样的一个 ISO 8601
字符串: 2010-05-08T23:41:54.000Z
并且不确定其中是否包含时区信息,用 strptime 解析会很令人头疼。我在使用中遇到了一些问题(请查看它们的追踪器),而 pyiso8601
已经好几年没有更新了。相比之下,dateutil 活跃并且对我有用:
from dateutil import parser
yourdate = parser.parse(datestring)
datetime.datetime.fromisoformat
函数。详情请参阅https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat - Yuri Ritvin自 Python 3.7 开始,无需使用外部库,您可以使用 fromisoformat
函数从 datetime
模块中获取:
datetime.datetime.fromisoformat('2019-01-04T16:41:24+02:00')
Python 2不支持%z
格式说明符,所以最好在可能的情况下明确使用Zulu时间:
datetime.datetime.strptime("2007-03-04T21:08:12Z", "%Y-%m-%dT%H:%M:%SZ")
strptime
?他们为什么不能使用一个更有意义的名称,而要沿用一个古老且糟糕的C语言名称呢? - Roman Starkovdatetime.datetime.fromisoformat(date_string)
。详见 https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat 和 https://dev59.com/8HVC5IYBdhLWcg3w-mVO#49784038。 - pabouk - Ukraine stay strong因为ISO 8601允许出现许多可选的冒号和破折号,基本格式为CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]
。如果你想使用strptime,需要首先去除这些变体。
目标是生成一个UTC日期时间对象。
如果您只想处理带有Z后缀的UTC基本情况,例如2016-06-29T19:36:29.3453Z
:
datetime.datetime.strptime(timestamp.translate(None, ':-'), "%Y%m%dT%H%M%S.%fZ")
如果您想处理时区偏移量,例如2016-06-29T19:36:29.3453-0400
或2008-09-03T20:56:35.450686+05:00
,请使用以下方法。这将把所有变体转换为没有可变分隔符的形式,例如20080903T205635.450686+0500
,使其更一致/更容易解析。import re
# This regex removes all colons and all
# dashes EXCEPT for the dash indicating + or - utc offset for the timezone
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', timestamp)
datetime.datetime.strptime(conformed_timestamp, "%Y%m%dT%H%M%S.%f%z" )
如果你的系统不支持%z
strptime 指令(你会看到类似于ValueError: 'z' is a bad directive in format '%Y%m%dT%H%M%S.%f%z'
的错误信息),那么你需要手动计算时间偏移量,从 Z
(UTC)开始。请注意,在 Python 版本<3 上,%z
可能无法在您的系统上正常工作,因为它依赖于 C 库支持,而 C 库的支持因系统/Python 构建类型(例如 Jython 、Cython 等)而异。import re
import datetime
# This regex removes all colons and all
# dashes EXCEPT for the dash indicating + or - utc offset for the timezone
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', timestamp)
# Split on the offset to remove it. Use a capture group to keep the delimiter
split_timestamp = re.split(r"([+|-])",conformed_timestamp)
main_timestamp = split_timestamp[0]
if len(split_timestamp) == 3:
sign = split_timestamp[1]
offset = split_timestamp[2]
else:
sign = None
offset = None
# Generate the datetime object without the offset at UTC time
output_datetime = datetime.datetime.strptime(main_timestamp +"Z", "%Y%m%dT%H%M%S.%fZ" )
if offset:
# Create timedelta based on offset
offset_delta = datetime.timedelta(hours=int(sign+offset[:-2]), minutes=int(sign+offset[-2:]))
# Offset datetime with timedelta
output_datetime = output_datetime + offset_delta
当比较非时区感知的日期时间与时区感知的日期时间时,您应该特别注意时区信息,否则可能会遇到问题。
最好始终使它们有时区意识(即使只是 UTC),除非您确切知道为什么不这样做没有任何用处。
#-----------------------------------------------
import datetime
import pytz
import dateutil.parser
#-----------------------------------------------
utc = pytz.utc
BERLIN = pytz.timezone('Europe/Berlin')
#-----------------------------------------------
def to_iso8601(when=None, tz=BERLIN):
if not when:
when = datetime.datetime.now(tz)
if not when.tzinfo:
when = tz.localize(when)
_when = when.strftime("%Y-%m-%dT%H:%M:%S.%f%z")
return _when[:-8] + _when[-5:] # Remove microseconds
#-----------------------------------------------
def from_iso8601(when=None, tz=BERLIN):
_when = dateutil.parser.parse(when)
if not _when.tzinfo:
_when = tz.localize(_when)
return _when
#-----------------------------------------------
我还没有尝试过,但pyiso8601承诺支持这个功能。
import datetime, time
def convert_enddate_to_seconds(self, ts):
"""Takes ISO 8601 format(string) and converts into epoch time."""
dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+\
datetime.timedelta(hours=int(ts[-5:-3]),
minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
return seconds
这也包括毫秒和时区。
如果时间是“2012-09-30T15:31:50.262-08:00”,则会转换为时间戳。
>>> import datetime, time
>>> ts = '2012-09-30T15:31:50.262-08:00'
>>> dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+ datetime.timedelta(hours=int(ts[-5:-3]), minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
>>> seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
>>> seconds
1348990310.26
双向转换:
从Epoch时间到ISO时间:
isoTime = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(epochTime))
ISO时间转换为Epoch时间:
epochTime = time.mktime(time.strptime(isoTime, '%Y-%m-%dT%H:%M:%SZ'))
time.strftime("%d-%m-%y %H:%M", time.localtime(EPOCH_TIME))
。 - whtyger