【问题标题】:Rounding time in PythonPython中的舍入时间
【发布时间】:2011-10-11 23:56:30
【问题描述】:

在 Python 中对时间相关类型执行 h/m/s 舍入操作并控制舍入分辨率的优雅、高效和 Pythonic 方式是什么?

我的猜测是它需要时间模运算。示例:

  • 20:11:13 %(10 秒)=>(3 秒)
  • 20:11:13 %(10 分钟)=>(1 分 13 秒)

我能想到的相关时间相关类型:

  • datetime.datetime \ datetime.time
  • struct_time

【问题讨论】:

  • 您是否要将日期四舍五入到最接近的“部分”(即 20:11:10 四舍五入到最接近的小时产生 20:00:00)或者 - 如您的示例所示 - 获取 余数四舍五入到最近的部分(即 20:11:10 到最近的小时产生 11:13)?
  • 对不起;对于“日期”,请阅读“时间”

标签: python datetime time modulo rounding


【解决方案1】:

我想我会以秒为单位转换时间,并从那时起使用标准模运算。

20:11:13 = 20*3600 + 11*60 + 13 = 72673 秒

72673 % 10 = 3

72673 % (10*60) = 73

这是我能想到的最简单的解决方案。

【讨论】:

  • 如果您想处理特殊情况,模 n 秒,其中 n 在 (2,3,4,5,10,12,15,20,30) 中,只需秒部分。
【解决方案2】:

您可以将两个时间都转换为秒,进行模运算

from datetime import time

def time2seconds(t):
    return t.hour*60*60+t.minute*60+t.second

def seconds2time(t):
    n, seconds = divmod(t, 60)
    hours, minutes = divmod(n, 60)
    return time(hours, minutes, seconds)

def timemod(a, k):
    a = time2seconds(a)
    k = time2seconds(k)
    res = a % k
    return seconds2time(res)

print(timemod(time(20, 11, 13), time(0,0,10)))
print(timemod(time(20, 11, 13), time(0,10,0)))

输出:

00:00:03
00:01:13

【讨论】:

    【解决方案3】:

    datetime.timedeltas怎么样:

    import time
    import datetime as dt
    
    hms=dt.timedelta(hours=20,minutes=11,seconds=13)
    
    resolution=dt.timedelta(seconds=10)
    print(dt.timedelta(seconds=hms.seconds%resolution.seconds))
    # 0:00:03
    
    resolution=dt.timedelta(minutes=10)
    print(dt.timedelta(seconds=hms.seconds%resolution.seconds))
    # 0:01:13
    

    【讨论】:

    • 这适用于datetime.time,但不适用于datetime.datetime,因为您没有考虑日期
    【解决方案4】:

    对于 datetime.datetime 舍入,请参阅此函数: https://stackoverflow.com/a/10854034/1431079

    使用示例:

    print roundTime(datetime.datetime(2012,12,31,23,44,59,1234),roundTo=60*60)
    2013-01-01 00:00:00
    

    【讨论】:

      【解决方案5】:

      我使用以下代码 sn-p 舍入到下一个小时:

      import datetime as dt
      
      tNow  = dt.datetime.now()
      # round to the next full hour
      tNow -= dt.timedelta(minutes = tNow.minute, seconds = tNow.second, microseconds =  tNow.microsecond)
      tNow += dt.timedelta(hours = 1)
      

      【讨论】:

      • 根本没有回答问题
      • 它实际上是唯一直接回答问题标题的答案,它是关于 rounding (恰好是我正在寻找的)。问题正文与标题相矛盾。这只是一个糟糕的问题。谢谢,PTH。
      • 小心:如果tNow 已经四舍五入到最接近的小时,那么这将增加一个小时而不是什么都不做。
      【解决方案6】:

      这会将时间数据四舍五入到问题中提出的分辨率:

      import datetime as dt
      
      current = dt.datetime.now()
      current_td = dt.timedelta(
          hours = current.hour, 
          minutes = current.minute, 
          seconds = current.second, 
          microseconds = current.microsecond)
      
      # to seconds resolution
      to_sec = dt.timedelta(seconds = round(current_td.total_seconds()))
      print(dt.datetime.combine(current, dt.time(0)) + to_sec)
      
      # to minute resolution
      to_min = dt.timedelta(minutes = round(current_td.total_seconds() / 60))
      print(dt.datetime.combine(current, dt.time(0)) + to_min)
      
      # to hour resolution
      to_hour = dt.timedelta(hours = round(current_td.total_seconds() / 3600))
      print(dt.datetime.combine(current, dt.time(0)) + to_hour)
      

      【讨论】:

        【解决方案7】:

        这是每小时舍入的有损*版本:

        dt = datetime.datetime
        now = dt.utcnow()
        rounded = dt.utcfromtimestamp(round(now.timestamp() / 3600, 0) * 3600)
        

        同样的原则可以适用于不同的时间跨度。

        *上述方法假定使用 UTC,因为任何时区信息都将在转换为时间戳时被销毁。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多