函数在django中的一个日期范围内给出了错误的一周总天数



我已经看了这个函数好几个小时了,似乎不明白为什么它没有给我预期的结果。我有一个生成日期时间开始和日期时间结束的测试。我想计算在这个时间范围内有多少"星期一"或任何给定的一天。

def day_count(week_day, start, end):
if week_day == 1:
day = 6
else:
day = week_day - 2
num_weekdays, remainder = divmod((end - start).days, 7)
if (day - start.weekday()) % 7 <= remainder:
return num_weekdays + 1
else:
return num_weekdays

要复制,这是我给它的数据:

end: 2020-08-22 00:00:00+02:00
start: 2020-08-20 22:15:55.371646+00:00
weekday: 6

我希望归还num_weekdays = 1

但我得到了num_weekdays = 0

我不知道如何解决这个问题,调试时num_weekdaysremainder也是0。

这就是我调用函数的方式:

total_day_count = day_count(params['dt_start__week_day'], params['dt_start__gte'], params['dt_end__lte'])

这就是我获取参数的方式:

params = {}
if self.request.GET.get('day') == 'Today':
params['dt_start__week_day'] = (timezone.now().weekday() + 1) % 7 + 1
elif is_valid_queryparam(self.request.GET.get('day')):
day_of_the_week = self.request.GET.get('day')
params['dt_start__week_day'] = (int(day_of_the_week) + 1) % 7 + 1
else:
params['dt_start__week_day'] = (timezone.now().weekday() + 1) % 7 + 1
if is_valid_queryparam(self.request.GET.get('date_start')):
unaware = datetime.strptime(self.request.GET.get('date_start'), '%Y-%m-%d')
params['dt_start__gte'] = unaware.replace(tzinfo=local_tz)
else:
dt = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
first_job = Job.objects.earliest('dt_start')
params['dt_start__gte'] = first_job.dt_start
if is_valid_queryparam(self.request.GET.get('date_end')):
unaware = datetime.strptime(self.request.GET.get('date_end'), '%Y-%m-%d')
params['dt_end__lte'] = unaware.replace(tzinfo=local_tz) + timedelta(days=1)
else:
dt = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
dt_aware = local_tz.localize(dt)
params['dt_end__lte'] = dt_aware + timedelta(days=1)

我不知道这是否有帮助,但这是一个测试:

class MachineDurationViewTestCase(CustomAPITestCase):
"""This testcase contains tests for the API endpoint MachineDurationView """
# todo once views and some of its variables were renamed, also apply these name changes here
fake = Faker()
def setUp(self) -> None:
self.fake.seed()
super(MachineDurationViewTestCase, self).setUp()
def test_a_single_job_that_occurs_in_the_space_of_one_hour(self):
"""
In this test a single job of 30 minutes is created occuring on the first hour on the current date. This means
that we should expect the endpoint to return an array of 24 value where the first item in the array has a value
of 0.5 (Because the first hour only occurs 1 time, and job lasts 30 minutes, machine occupancy is 50%)
"""
dt = timezone.localtime()
dt_start = dt.replace(hour=0, minute=15)
dt_end = dt.replace(hour=0, minute=45)
# dt_end = timezone.datetime(d.year, d.month, d.day, hour=0, minute=45)
# dt_start = timezone.make_aware(timezone.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0))
print(dt_start)
print(dt_end)
job = JobFactory(dt_start=dt_start, dt_end=dt_end)
print(job.dt_start)
# Query the dbase to ensure the job is created
self.assertEqual(Job.objects.all().count(), 1)
# Force create/login a user to access the http mocking client
# (I don't care about authentication or permissions in this test)
self.client.force_login(user=UserFactory(is_superuser=True))
response = self.client.get(reverse('data_app:machine_avg'))
self.assertEqual(response.status_code, 200)
print(response.data['machines'])
self.assertNotEqual(response.data['machines'][0], 0.0, "Since we create a job on the first hour, we expect the"
"first item of the array not to be zero.")
self.assertEqual(response.data['machines'][0], 0.5, "Since we create a single job of 30 minutes that occurs on "
"the current date, the value on the given hour should be"
"0.5 (50% occupancy)")
# job = JobFactory(dt_start=)

我认为您的输入数据有问题。这似乎对我有效:

from datetime import date
start = date(2020, 8, 20)
end = date(2020, 8, 22)
day_count(6, start, end)

这将返回所需的输出1。我的日期类型是:<class 'datetime.date'>

可以使用日期对象的weekday((方法来实现计算日期范围内具体工作日总数的函数:

from datetime import date, timedelta
def days_count(weekdays: list, start: date, end: date):
dates_diff = end-start
days = [start + timedelta(days=i) for i in range(dates_diff.days)]
return len([day for day in days if day.weekday() in weekdays])

start = date(2020, 8, 20)
end = date(2020, 8, 22)
# total of weekend days between that range (end date is excluded)
print(days_count([5, 6], start, end)) # outputs: 0

相关内容

最新更新