Python 中的时间增量

Timedeltas in Python

我知道 Python 中有一些关于使用 timedelta 对象的帖子,并且 Python 文档足够清晰,可以理解所有内容。但我无法弄清楚一件事。假设我们有两个日期:

t1 = 'Fri 11 Feb 2078 00:05:21 +0400'
t2 = 'Mon 29 Dec 2064 03:33:48 -1100' 

我使用下面的代码解析了 t1t2 以在几秒钟内找出它们之间的区别:

def offset(arg):
    return timedelta(hours = arg / 100, minutes = arg % 100)

def normalize(time, offset, sign):
    return time+offset if sign == '-' else time-offset

def main():
    t1offset = offset(int(t1[-5:]))
    t2offset = offset(int(t2[-5:]))

    t1 = normalize(datetime.strptime(t1[:-6], 
                   "%a %d %b %Y %H:%M:%S"), t1offset, t1[-5])
    t2 = normalize(datetime.strptime(t2[:-6], 
                   "%a %d %b %Y %H:%M:%S"), t2offset, t2[-5])

    if t1>t2:
        print (t1-t2).total_seconds()
    elif t2>t1:
        print (t2-t1).total_seconds()
    else:
        print 0

正确答案是 |t1-t2| = 413962293,而我的答案是 414041493。相差 79200 秒 -> 22 小时。我究竟做错了什么?我跳过了什么或者我应该考虑什么来解决这个问题?

这不是用时区解析日期的最佳方式,但如果你想这样,那是你的错误:

def normalize(time, offset, sign):
    return time+offset if sign == '+' else time-offset
                                   ^

标准化应该是相反的。

如果您使用的是 Python 3+(您应该这样做),您可以这样做:

datetime.strptime(t1, "%a %d %b %Y %H:%M:%S %z")

时区说明符在 Python 2.x

中不起作用

或使用dateutils库:

import dateutil
dateutil.parser.parse('Fri 11 Feb 2078 00:05:21 +0400')

编辑:以原始方式进行比较的更好方法是完全放弃符号比较并依赖已解析数字的符号:

def offset(arg):
    return -timedelta(hours = arg / 100, minutes = arg % 100)

def normalize(time, offset):
    return time+offset

您将偏移量的符号放入 offset 函数中。

'Fri 11 Feb 2078 00:05:21 +0400'[-5:] == '+0400'

我觉得应该只有数字:

'Fri 11 Feb 2078 00:05:21 +0400'[-4:] == '0400'

这样你的偏移量就会有负值,并且在规范化函数中你会再次应用符号。试试这个:

def main():
    t1offset = offset(int(t1[-4:]))
    t2offset = offset(int(t2[-4:]))

    t1 = normalize(datetime.strptime(t1[:-6], 
           "%a %d %b %Y %H:%M:%S"), t1offset, t1[-5])
    t2 = normalize(datetime.strptime(t2[:-6], 
                   "%a %d %b %Y %H:%M:%S"), t2offset, t2[-5])

    if t1>t2:
        print (t1-t2).total_seconds()
    elif t2>t1:
        print (t2-t1).total_seconds()
    else:
        print 0

但是,您真的不应该像这样使用硬编码字符串索引来解析字符串时间戳。

时间格式与the date/time format used in emails类似。您可以使用 email 模块来解析它:

>>> from email.utils import parsedate_tz, mktime_tz
>>> ts1 = mktime_tz(parsedate_tz('Fri 11 Feb 2078 00:05:21 +0400'))
>>> ts2 = mktime_tz(parsedate_tz('Mon 29 Dec 2064 03:33:48 -1100'))
>>> ts1 - ts2
413962293