0

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

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

这就是我苦苦挣扎的地方:我需要将工作的持续时间按小时分开。我有一个开始时的日期时间和结束时的日期时间。我也有总时长。例如:假设作业开始于 11h15,结束于 12h15。这意味着第 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)})
4

1 回答 1

0

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

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 分钟。

但这只会工作一天——如果一项工作跨越多天,你必须创建更复杂的结构,例如二维数组,其中第一维是“天”(例如一个月),然后是一个小时.

于 2020-08-17T20:49:46.203 回答