给定开始日期和结束日期,给出与一天中的几个小时对应的 24 个值数组中的持续时间

given a date start and date end, give me the duration in an array of 24 values corresponding to hours of the day

我对 Django rest 框架和堆栈溢出非常陌生,我一直在努力寻找一个标题,所以请随时提供更好的选择。

我有一组发布到数据库的工作。这些工作现在按机器和给定的时间分组。现在我只显示每小时的作业总数。我的 API 终点现在看起来像这样: Api end point

这是我苦苦挣扎的地方:我需要按小时分隔工作的持续时间。我在开始时有一个日期时间,在结束时有一个日期时间。我也有总的持续时间。 例如:假设一项工作从 11 点 15 分开始,到 12 点 15 分结束。这意味着第 11 小时的总持续时间为 45 分钟。对于第 12 小时,持续时间为 15 分钟。

我想在 11h15 和 12h00 之间传递时间,然后在 12h15 和 13h00 之间传递时间。但我不确定我该怎么做。另请注意,有些工作持续一个多小时,有些甚至超过一天。我确信在 python 中有使用 timedelta 执行此操作的特定方法。我只是没有足够的经验来理解这一点。

这是 API 终点的当前代码:

class MachineDurationViewSet(APIView):
authentication_classes = (SessionAuthentication, DataAppClientTokenAuthentication)

def get(self, request):
    # get names of all machines
    machine_names_queryset = Machine.objects.all()
    machine_names = []
    for obj in machine_names_queryset:
        machine_names.append(obj.name)
        
    machine_list = {}
    sum = []
    queryset = Job.objects.all()

    # per machine, get dur for a given hour,use names to filter
    for name in machine_names:
        qs_grouped_per_machine = queryset.filter(machine__name=name)
        queryset_machine_start = qs_grouped_per_machine.annotate(hour=ExtractHour('dt_start'))
        queryset_machine_end = qs_grouped_per_machine.annotate(hour=ExtractHour('dt_end'))
        for n in range(0,24):
            job_start = queryset_machine_start.filter(hour=n)
            for job in job_start:
                print(job.dt_start)
            sum.append(job_start.count())
            machine_list[name] = sum
        sum = []
    return Response({"machines": machine_list, "machine_count": len(machine_names)})

这个似乎可以完成工作,解释在代码中。希望你能把它提取到一个函数中并在你的上下文中使用:

from datetime import datetime
from datetime import timedelta

start = datetime(2019, 2, 15, 0, 38, 42) #datetime.now(tz=None)
hours_added = timedelta(minutes = 150) # change to eg. 1500
end = datetime(2019, 2, 15, 0, 39, 1) #start + hours_added
diff = end - start

print("Start ", start)
print("End", end)

dates_spent = []
SECONDS_IN_HOUR = 3600
full_hours = int(diff.seconds / 3600) + 1 # get hours the task took rounded (ceiling)
for i in range(full_hours + 1): # add '1' because we want to include last 'touched' hour as well
    if i == 0:
        # store first datetime
        dates_spent.append(start)
    if i == full_hours or full_hours == 1: # job spanned only some minutes within same hour
        # store last datetime and ignore next hour
        dates_spent.append(end)
        break
    next_hh = start + timedelta(hours=i + 1)
    # truncate minutes as we need full hours
    next_hh = datetime(next_hh.year, next_hh.month, next_hh.day, next_hh.hour)
    dates_spent.append(next_hh)

print("***")
for d in dates_spent:
    print(d)
print("***")

minutes_as_array = [None]*24

for i in range(len(dates_spent) - 1):
    # get time difference between 'next' hour spent and 'current'
    minutes_in_hour_spent = dates_spent[i + 1] - dates_spent[i]
    print("minutes spent: {}, in hour: {}".format(minutes_in_hour_spent, dates_spent[i]))
    minutes_as_array[dates_spent[i].hour] = minutes_in_hour_spent.seconds / 60

print("===")
print(minutes_as_array)

对于我的测试数据,它产生:

Start  2019-02-15 00:38:42
End 2019-02-15 00:39:01
***
2019-02-15 00:38:42
2019-02-15 00:39:01
***
minutes spent: 0:00:19, in hour: 2019-02-15 00:38:42
===
[0.31666666666666665, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]

因此,在索引 11 上我们将有 ~25 分钟,然后是 60 分钟,然后是 60 分钟和 ~4 分钟。

但这只能工作一天 - 如果一项工作跨越多天,您将不得不创建更复杂的结构,例如第一个维度为 'day' 的二维数组(例如,在一个月),然后一个小时。