【问题标题】:Python DateTime :: Round Down 5 Minutes? (No pandas)Python DateTime :: 四舍五入 5 分钟? (没有熊猫)
【发布时间】:2023-01-14 02:02:51
【问题描述】:

我需要一个 Python3 函数来将 DateTime 对象向下舍入到最接近的 5 分钟。是的,这已在之前的 SO 帖子 herehere 甚至 here 中讨论过,但我没有运气实施他们的解决方案。注意:我可以不是使用熊猫

我想要一个函数,给定以下 DateTime (%Y%m%d%H%M) 对象,返回以下内容:

INPUT         OUTPUT
202301131600  202301131600
202301131602  202301131600
202301131604  202301131600
202301131605  202301131605
202301131609  202301131605
202301131610  202301131610

这是我的代码,使用 timedelta 作为机制:

from datetime import datetime
from datetime import timedelta

def roundDownDateTime(dt):
    # Arguments:
    #   dt      DateTime object
    delta = timedelta(minutes=5)
    return dt - (datetime.min - dt) % delta

tmpDate = datetime.now()
# Print the current time and then rounded-down time:
print("\t"+tmpDate.strftime('%Y%m%d%H%M')+"  -->  "+(roundDownDateTime(tmpDate)).strftime('%Y%m%d%H%M') )

这是我多次测试代码时的一些输出:

202301131652  -->  202301131650
202301131700  -->  202301131655
202301131701  -->  202301131657

呃,不好!我将我的功能调整为:

def roundDownDateTime(dt):
    # Arguments:
    #   dt      DateTime object
    n = dt - timedelta(minutes=5)
    return datetime(year=n.year, month=n.month, day=n.day, hour=n.hour)

但那是平更差:

202301131703  -->  202301131600
202301131707  -->  202301131700
202301131710  -->  202301131700

在弄清楚这个基本的 DateTime 算术东西时,我都不敢恭维;谁能看到我的错误?

【问题讨论】:

  • 我不知道 % timedelta 应该做什么,但显然这对你来说是错误的方法。我会尝试直接使用会议记录。
  • @MarkRansom 谢谢马克,我编辑了我的 OP 以包括我尝试timedelta 的原因。直接处理会议记录似乎很麻烦,我有点希望有一种更简单的方法。谢谢你的建议!

标签: python-3.x datetime rounding


【解决方案1】:

您有 (datetime.min - dt) 向后 - 这会导致负日期时间。你不是说(dt - datetime.min),例如交换你得到:

In []:
def roundDownDateTime(dt, delta=timedelta(minutes=5)):
    return dt - (dt - datetime.min) % delta

tmpDate = datetime.now()
tmpDate

Out[]:
datetime.datetime(2023, 1, 13, 11, 36, 7, 821196)

In []:
roundDownDateTime(tmpDate)

Out[]:
datetime.datetime(2023, 1, 13, 11, 35)

In []:
roundDownDateTime(tmpDate, timedelta(minutes=10)

Out[]:
datetime.datetime(2023, 1, 13, 11, 30)

【讨论】:

  • 作为解释:对于 OP 链接的 ceil 案例,否定的 timedelta 是正确的,因为他们想弄清楚要计算多少添加,即他们想要delta - ((dt - datetime.min) % delta),这等于(datetime.min - dt) % delta。弄清楚我们需要多少时间减去对于楼层,需要删除该表达式的 delta - 部分
【解决方案2】:

我想我会倾向于获取时间戳并将其四舍五入然后转换回日期时间:

def round_datetime(dt, secs):
    return datetime.datetime.fromtimestamp(secs * (dt.timestamp() // secs))

你可以测试:

import datetime
import time

def round_datetime(dt, secs):
    return datetime.datetime.fromtimestamp(secs * (dt.timestamp() // secs))

while True:
    now = datetime.datetime.now()
    print(now, round_datetime(now, 5 * 60))
    time.sleep(1)

【讨论】:

    【解决方案3】:

    此答案假定您的日期时间的粒度为一分钟。

    由于您只能通过四舍五入到最接近的 5 分钟来影响分钟数,因此只需计算出您需要减去多少分钟:

    def roundDownDateTime(dt):
        delta = datetime.timedelta(minutes=1) * (dt.minute % 5)
        return dt - delta
    

    去测试:

    import datetime
    
    expio = [['202301131600', '202301131600'],
     ['202301131602', '202301131600'],
     ['202301131604', '202301131600'],
     ['202301131605', '202301131605'],
     ['202301131609', '202301131605'],
     ['202301131610', '202301131610']]
    
    for i, eo in expio:
        o = roundDownDateTime(datetime.datetime.strptime(i, "%Y%m%d%H%M")).strftime("%Y%m%d%H%M")
        assert eo == o
    

    断言全部为真

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-16
      • 1970-01-01
      • 2017-07-25
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 1970-01-01
      相关资源
      最近更新 更多