Вычисление дней между датами в Python?

#python

#python

Вопрос:

Для этого я задал домашнее задание по курсу. Все шло хорошо, пока я не заметил, что один из тестовых примеров не работает, пытаясь получить дни между 2012-1-1 и 2013-1-1 .

Я предположил, что это будет 366, дополнительный день, так как 2012 был високосный год. Этот код, похоже, угадывает 365, мой преподаватель отметил ответ как 360.

Он сказал что-то о «просто сделайте все месяцы 30 днями», поэтому я думаю, что его 360 это как-то связано с этим? В любом случае, это не оправдывает моего угадывания кода, 365 когда он должен угадываться 366 .

Вывод такой, как показано

Тест пройден! ПОЗДРАВЛЯЕМ
Тест с данными: (2012, 1, 1, 2013, 1, 1) не пройдено 365, должно быть пройдено 360
Тестовый пример пройден! ПОЗДРАВЛЯЕМ

 daysOfMonths = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] 

def is_leap_year(year):
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)

def get_days_from_year(year):
    days = year * 365
    i = 0

    while i < year:
        i  = 1
        if is_leap_year(i):
            days  = 1

    return days

def get_days_from_month(month, year):
    days = 0
    i = 0

    while i < month:
        if i == 1 and is_leap_year(year):
            days  = daysOfMonths[i]   1
        else:
            days  = daysOfMonths[i]
        i  = 1

    return days

def get_days_from_date(year, month, day): 
    days_in_year = get_days_from_year(year)
    days_in_month = get_days_from_month(month - 1, year)
    days = days_in_year   days_in_month   day
    return days

def daysBetweenDates(year1, month1, day1, year2, month2, day2):
    first_date_days = get_days_from_date(year1, month1, day1)
    second_date_days = get_days_from_date(year2, month2, day2)


    if first_date_days > second_date_days:
        return first_date_days - second_date_days
    else:
        return second_date_days - first_date_days

def test():
    test_cases = [((2012,9,30,2012,10,30),30), 
                  ((2012,1,1,2013,1,1),360),
                  ((2012,9,1,2012,9,4),3)]
    for (args, answer) in test_cases:
        result = daysBetweenDates(*args)
        if result != answer:
            print("Test with data:", args, "failed passed", result, "should of passed", answer)
        else:
            print("Test case passed! CONGRATULATIONS")

test()
  

Комментарии:

1. Напишите тест для каждой вызываемой вами функции и найдите ту, которая возвращает что-то отличное от того, что вы ожидали. В качестве альтернативы, используйте отладчик для пошагового выполнения ваших вычислений.

2. Это не связано с проблемой, но это должно было быть «должно иметь», а не «должно из».

Ответ №1:

Вы увеличиваете i не в том месте. У вас есть:

 while i < year:
    i  = 1
    if is_leap_year(i):
        days  = 1
  

но должно быть:

 while i < year:
    if is_leap_year(i):
        days  = 1
    i  = 1
  

из-за этого все ваши високосные годы уменьшены на 1 (2011 по сравнению с 2012, 2015 по сравнению с 2016 и т.д.)

Комментарии:

1. значит, во всех месяцах по 30 дней, кроме февраля в високосный год?

2. Нет. Просто в феврале есть дополнительный день в високосный год … 29 против 28. — Ожидание 360 кажется мне неправильным, как и для OP. Внесение изменений, о которых я упоминаю, дает оператору результат, который он ожидает … 366.

3. если вам нужно реальное значение, просто используйте (datetime.datetime(Y,M,D) - datetime.datetime(Y1,M1,D1)).days

4. @Joran, я думаю, он должен делать это без каких-либо специальных функций даты. Я предполагаю, что это домашнее задание, в котором есть это условие.

Ответ №2:

Он сказал что-то о «просто сделайте все месяцы 30 днями», так что

 def get_range(year1,month1,day1,year2,month2,day2):
    """
    assumes all months have 30 days, with no leap years
    ~ for some weird reason i dont understand
   (probably so you dont use builtin datetime)

    """
    days_difference = (year2-year1)*360
    days_difference  = (month2-month1)*30
    return days_difference   day2-day1


print(get_range(2012, 1, 1, 2013, 1, 1))
  

если вы хотите получить фактическое количество дней между двумя датами

 from datetime import datetime
def get_real_range(year1,month1,day1,year2,month2,day2):
    return (datetime(year2,month2,day2) - datetime(year1,month1,day1)).days