在不使用任何外部库的情况下将ISO8601格式转换为python中的秒

时间:2012-08-31 22:37:54

标签: python datetime time iso8601

我正在尝试使用标准库将ISO8601时间格式转换为python中的秒/ unix /纪元时间。

时间格式='2012-09-30T15:31:50.262-08:00'

基本上,时间将是一个字符串,它解析并将其转换回秒。

切片和选择我们想要的值是可能的,但还有比这更好的方法吗?

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

2 个答案:

答案 0 :(得分:2)

Celada回答后的最终正确答案。下面我已经验证了xml.iso8601.parse的输出也返回与函数生成的结果相同的结果。感谢Celada提供原始代码的问题。

>>> import calendar, datetime, time 
>>> def convert_enddate_to_seconds(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 = calendar.timegm(dt.timetuple()) + dt.microsecond/1000000.0
...   return seconds
... 
>>> import iso8601
>>> ts = '2012-09-30T15:31:50.262-08:00'
>>> iso8601.parse(ts)
1349047910.0
>>> convert_enddate_to_seconds(ts)
1349047910.26
>>> 

答案 1 :(得分:1)

首先,您的示例代码中至少有4个错误:

  • 您的strptime格式需要小数点和秒后的数字,但您的示例输入没有。
  • ts[:-7]位没有正确地对字符串的末尾进行切片。 ts[:-6]似乎更正确:你想要在字符串末尾切出6个字符(tz小时为2,tz分为2,1为1,+或 - )。 / LI>
  • 您正在添加时区偏移,而应将其减去。您必须从东半球时区给出的时间减去小时和分钟才能返回UTC,而不是添加它们。
  • 您正在使用time.mktime(),假设在当地时间给出了时间段,但它实际上是UTC。您需要使用calendar.timegm()代替。

这是你的代码更新到但后三个问题。第一个问题仍然存在,因为我不知道你是否打算在输入字符串中强制存在小数秒。你可以进一步调整它。

import datetime, time, calendar

def convert_enddate_to_seconds(ts):
    """Takes ISO 8601 format(string) and converts into epoch time."""
    dt = datetime.datetime.strptime(ts[:-6],'%Y-%m-%dT%H:%M:%S.%f')-\
                datetime.timedelta(hours=int(ts[-5:-3]),
                minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
    seconds = calendar.timegm(dt.timetuple()) + dt.microsecond/1000000.0
    return seconds

使用2010-01-04T12:15:30.1+01:00作为测试输入,输出1262603730.1,这是正确的。

关于你的问题:不,如果你只是将自己限制在标准库中,那么你不可能比这更简洁。