【问题标题】:subtract two times in python在python中减去两次
【发布时间】:2011-07-12 16:56:46
【问题描述】:

我有两个 datetime.time 值,exitenter,我想做类似的事情:

duration = exit - enter

但是,我收到此错误:

TypeError: 不支持的操作数类型 -: 'datetime.time' 和 '日期时间.时间

如何正确执行此操作?一种可能的解决方案是将time 变量转换为datetime 变量,然后进行减法运算,但我相信你们一定有更好更干净的方法。

【问题讨论】:

    标签: python datetime timedelta


    【解决方案1】:

    试试这个:

    from datetime import datetime, date
    
    datetime.combine(date.today(), exit) - datetime.combine(date.today(), enter)
    

    combine 构建一个可以减去的日期时间。

    【讨论】:

    • @IgnacioVazquez-Abrams 指出,可以使用datetime(1,1,1,0,0,0) 而不是date.today()
    • 不要命名datetime exit,因为exit 是一个内置函数。
    • 使用python 2.7,我的combine 模块中没有combine 方法:AttributeError: 'module' object has no attribute 'combine'
    • mtoloo: 有datetime 模块,里面有一个datetime 对象。里面的对象有combine 方法。如果你只是简单地导入datetime(像这样:import datetime),那么你后面需要做的就是这个datetime.datetime.combine
    • 很少见的情况是您在某个时间(例如 23:59:59:9999)调用此函数。在这种情况下,之前的 date.today() 和之后的 date.today() 将返回不同的值。最好将值 date.today() 赋予变量。
    【解决方案2】:

    用途:

    from datetime import datetime, date
    
    duration = datetime.combine(date.min, end) - datetime.combine(date.min, beginning)
    

    使用date.min 更加简洁,即使在午夜也能正常工作。

    date.today() 可能不是这种情况,如果第一次调用发生在 23:59:59 并且下一次调用发生在 00:00:00,则可能会返回意外结果。

    【讨论】:

    • 同意你的看法。
    【解决方案3】:

    而不是使用时间尝试timedelta:

    from datetime import timedelta
    
    t1 = timedelta(hours=7, minutes=36)
    t2 = timedelta(hours=11, minutes=32)
    t3 = timedelta(hours=13, minutes=7)
    t4 = timedelta(hours=21, minutes=0)
    
    arrival = t2 - t1
    lunch = (t3 - t2 - timedelta(hours=1))
    departure = t4 - t3
    
    print(arrival, lunch, departure)
    

    【讨论】:

    【解决方案4】:

    python timedelta 库应该可以满足您的需求。当您减去两个 datetime 实例时,将返回 timedelta

    import datetime
    dt_started = datetime.datetime.utcnow()
    
    # do some stuff
    
    dt_ended = datetime.datetime.utcnow()
    print((dt_ended - dt_started).total_seconds())
    

    【讨论】:

      【解决方案5】:

      您有两个 datetime.time 对象,因此您只需使用 datetime.timedetla 创建两个 timedelta,然后像现在一样使用“-”操作数进行减法。以下是不使用日期时间进行两次减法的示例方法。

      enter = datetime.time(hour=1)  # Example enter time
      exit = datetime.time(hour=2)  # Example start time
      enter_delta = datetime.timedelta(hours=enter.hour, minutes=enter.minute, seconds=enter.second)
      exit_delta = datetime.timedelta(hours=exit.hour, minutes=exit.minute, seconds=exit.second)
      difference_delta = exit_delta - enter_delta
      

      difference_delta 是您可以根据自己的原因使用的差异。

      【讨论】:

      • 可以将 timedelta 对象转换回 datetime 吗?我的意思是我们有 difference_delta .seconds(),有没有办法取回日期时间或时间对象?谢谢
      • 是的。 datetime.min + delta
      【解决方案6】:

      datetime.time 不支持这一点,因为以这种方式减去时间几乎没有意义。如果您想这样做,请使用完整的datetime.datetime

      【讨论】:

      • 如果您从您的域中知道两个datetime.time 对象ab 来自同一天,并且b > a,那么操作b - a 具有完美的意义。
      • 即使他们不是同一天,它仍然很有意义。至少和arctan(0) = (0, pi, 2pi, ...) 一样有意义,但我们只是不关心第一个值之后的任何值。所以,4:00 - 20:008:00 - 它也是 (32:00, 56:00, ... ),但谁在乎呢?
      • 此外,Python 甚至无法保持一致。如果 a - b 对于两个时间对象没有意义,那么 a > b 或 a
      • 说它没有意义是主观的,但我知道你来自哪里。将两次相加对我来说似乎是毫无意义的表示。我认为减去两个时间值应该返回一个时间增量。如果那个 timedelta 恰好是负数,那就这样吧。我想知道的是为什么python不能从时间中加减timedelta来返回新的时间值。
      【解决方案7】:

      datetime.time 做不到 - 但你可以使用 datetime.datetime.now()

      start = datetime.datetime.now()
      sleep(10)
      end = datetime.datetime.now()
      duration = end - start
      

      【讨论】:

        【解决方案8】:
        import datetime
        
        def diff_times_in_seconds(t1, t2):
            # caveat emptor - assumes t1 & t2 are python times, on the same day and t2 is after t1
            h1, m1, s1 = t1.hour, t1.minute, t1.second
            h2, m2, s2 = t2.hour, t2.minute, t2.second
            t1_secs = s1 + 60 * (m1 + 60*h1)
            t2_secs = s2 + 60 * (m2 + 60*h2)
            return( t2_secs - t1_secs)
        
        # using it
        diff_times_in_seconds( datetime.datetime.strptime( "13:23:34", '%H:%M:%S').time(),datetime.datetime.strptime( "14:02:39", '%H:%M:%S').time())
        

        【讨论】:

          【解决方案9】:

          我的情况和你类似,最后我使用了名为 arrow 的外部库。

          这是它的样子:

          >>> import arrow
          >>> enter = arrow.get('12:30:45', 'HH:mm:ss')
          >>> exit = arrow.now()
          >>> duration = exit - enter
          >>> duration
          datetime.timedelta(736225, 14377, 757451)
          

          【讨论】:

          • 这里你只是在演示减去完整的日期时间对象,而不是原始问题中的时间
          【解决方案10】:

          timedelta 接受负 (-) 时间值。所以它可以简单如下(单行)

          duration = datetime.timedelta(hours=exit.hour-enter.hour, minutes=exit.minute-enter.minute)
          

          运行测试

          import datetime
          
          enter = datetime.time(hour=1, minute=30)
          exit = datetime.time(hour=2, minute=0)
          duration = datetime.timedelta(hours=exit.hour-enter.hour, minutes=exit.minute-enter.minute)
          
          >>> duration
          datetime.timedelta(seconds=1800)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-31
            • 1970-01-01
            • 2017-09-29
            相关资源
            最近更新 更多