如何将时间对象分配到垃圾箱?

时间:2019-12-17 21:40:05

标签: python date datetime time comparison-operators

我有一个需要分配给时间窗口的时间列表(7、9、12、15、18),以确保每个时间窗口都由列表中的元素覆盖。

from datetime import date, time, datetime

def nearest(items, target):
    return min(items, key=lambda x: abs(x - target))

time_list = [datetime.datetime(2019, 12, 17, 7, 30), 
             datetime.datetime(2019, 12, 17, 9, 0), 
             datetime.datetime(2019, 12, 17, 16, 0), 
             datetime.datetime(2019, 12, 17, 18, 30), 
             datetime.datetime(2019, 12, 17, 21, 30), 
             datetime.datetime(2019, 12, 17, 12, 30), 
             datetime.datetime(2019, 12, 17, 19, 0), 
             datetime.datetime(2019, 12, 17, 0, 0), 
             datetime.datetime(2019, 12, 17, 14, 30)]

target_times = [datetime.combine(date.today(),time(i,0)) for i in range(6,19,3)]
coverage = [abs(nearest(time_list, t)-t)<time(1,30) for t in target_times]

所需的输出:

[True, True, True, True, True]

当前返回一个“ <”错误,我可以解决这个错误,但是我不确定这是否是完成我想做的最好的方法。我有numpy和scipy库可用,并且可能可以得到其他库。

3 个答案:

答案 0 :(得分:1)

这是我根据此问题How to check if the current time is in range in python?提出的解决方案。它可以工作,但我想知道是否有更好的解决方案。

def time_in_range(start, end, x):
    today = timezone.localtime().date()
    start = timezone.make_aware(datetime.combine(today, start))
    end = timezone.make_aware(datetime.combine(today, end))
    x = timezone.make_aware(datetime.combine(today, x))
    if end <= start:
        end += timedelta(days=1) # tomorrow!
    if x <= start:
        x += timedelta(days=1) # tomorrow!
    return start <= x <= end

downloaded = [False, False, False, False, False]
times = [time(i,0) for i in [5,8,10,13,16,20]]
for i in range(5):
    for start_time in start_times:
        if time_in_range(times[i], times[i+1], start_time):
            downloaded[i] = True

答案 1 :(得分:1)

您当前的问题的答案是,您正在尝试将timedelta ob对象与time对象进行比较。在这种情况下,您将希望像这样创建timedelta对象:

timedelta(hours=1, minutes=30)

代替

time(1,30)

答案 2 :(得分:0)

您不妨在这里使用pandas;因为它具有处理垃圾箱和区间的内置方法。

在这种情况下,您有四(4)个时间间隔:

  1. [7至9)
  2. [9到12)
  3. [12到15)
  4. [15到18)
  5. ...还有应该再间隔18到24吗?

“ [”表示包含性,“)”表示排除性。

您可以将time_list加载到熊猫数据框中:

import pandas as pd

df = pd.DataFrame(time_list,columns=['timestamp']) # `columns` is how you name the column(s)

然后,我建议使用pandas的原因是它具有一个名为.cut()的有用功能,可以对值进行分箱。

>>> bins = [7, 9, 12, 15, 18]
>>> pd.cut(df['timestamp'].dt.hour,bins=bins).unique().dropna().sort_values()
[(7, 9], (9, 12], (12, 15], (15, 18]]

然后您可以像这样测试上述操作的结果的适当长度(减去1的原因是因为有五个箱:

>>> covered_intervals = _ # an underscore gets the most recent value in the interpreter
>>> len(covered_intervals) == len(bins) - 1
True

如果您需要布尔值列表,则可以执行以下操作:

result = []
for i in covered_intervals:
    if i.left in bins:
        result.append(True)
    else:
        result.append(False)