【问题标题】:Timedeltas in PythonPython中的时间增量
【发布时间】:2015-09-07 13:57:14
【问题描述】:

我知道有一些关于在 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 小时。我究竟做错了什么?我跳过了什么或者我应该考虑什么来解决这个问题?

【问题讨论】:

  • 谁投票结束,这是一个完全有效的问题,有足够的代码可以轻松重现问题。
  • @Andrey 但它不是重现问题的 minimal 代码(请参阅minimal reproducible example),因为 OP 未能进行基本的二进制搜索调试。跨度>
  • @jonrsharpe 代码不是绝对最小但足够小,不完美但很好理解问题。这个问题还不够糟糕,可以关闭。
  • 提示:t1:Fri 11 Feb 2078 00:05:21 +0400 --> datetime.datetime(2078, 2, 10, 20, 5, 21) 而 t2:Mon 29 Dec 2064 03:33:48 -1100 --> datetime.datetime(2064, 12, 28, 16, 33, 48)。那么+0400-1100 都会减少转换时间?

标签: python timedelta python-datetime


【解决方案1】:

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

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

我认为应该只有数字:

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

这样,您的偏移量具有负值,并且在 normalize 函数中您再次应用符号。试试这个:

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

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

【讨论】:

  • hege_hegedus,您的回答足以帮助我解决问题。我只是跳过了我再次在规范化函数中应用符号:)
  • @hebius 很高兴为您提供帮助,也很高兴您的代码能够正常工作。如果您没有其他问题,您能接受这个答案吗?
  • 做人 :) 多一次感谢您的帮助 :)
【解决方案2】:

时间格式类似于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

【讨论】:

    【解决方案3】:

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

    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 中不起作用

    或者使用dateutilslib:

    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
    

    【讨论】:

      猜你喜欢
      • 2015-03-18
      • 1970-01-01
      • 2021-01-10
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-17
      • 1970-01-01
      相关资源
      最近更新 更多