Найти дату следующего условия

#python #date

#python #Дата

Вопрос:

Давайте будем иметь две переменные:

  1. start_date
  2. days_of_months::list (пример: [1,2,10,31])

Вывод: дата> = start_date, которая («%d») = один из членов списка. Дата вывода должна быть как можно ближе к start_date .

Примеры

start_date: 2020-11-17

days_of_month: [5,10,20]

вывод: 2020-11-20

start_date: 2020-11-17

days_of_month: [5,10]

вывод: 2020-12-05

start_date: 2020-12-17

days_of_month: [5,10]

вывод: 2021-01-05

start_date: 2021-02-17

days_of_month: [5,10,31]

вывод: 2021-03-05

start_date: 2021-04-17

days_of_month: [31]

вывод: 2021-05-31 (апрель 2021 года не имеет 31 дня)

Предлагаемый ответ:

 from calendar import monthrange
from datetime import datetime
from datetime import timedelta

def find_condition_date(start_date,days_month_list):
    year = int(start_date.strftime("%Y"))
    month = int(start_date.strftime("%m"))
    day = int(start_date.strftime("%d"))
    
    current_month_days = monthrange(year, month)[1]
    
    if(day in days_month_list):
        return start_date
    else:
        for day_of_month_selected in days_month_list:
            if(day_of_month_selected>day and day_of_month_selected<=current_month_days):
                add_days = day_of_month_selected - day
                start_date = start_date   timedelta(days=add_days)
                return start_date
            
        selected_index = 0
        total_days_selected = len(days_month_list)
        if(month==12):
            year =1
            month = 1
        else:
            month  =1
        current_month_days = monthrange(year,month)[1]
        
        while(True):
            if(selected_index<total_days_selected):
                first_day_of_month_selected = int(days_month_list[selected_index])
                if(current_month_days>=first_day_of_month_selected):
                    return datetime(year,month,first_day_of_month_selected).date()
                else:
                    selected_index = 0
                    if(month==12):
                        year =1
                        month = 1
                    else:
                        month  =1
                    current_month_days = monthrange(year,month)[1]
            else:
                selected_index = 0
                if(month==12):
                    year =1
                    month = 1
                else:
                    month  =1
                current_month_days = monthrange(year,month)[1]

#Example 1          
start_date = datetime(2020,11,17)
days_month_list = [5,10,20]
print(find_condition_date(start_date,days_month_list))

#Example 2          
start_date = datetime(2020,11,17)
days_month_list = [5,10]
print(find_condition_date(start_date,days_month_list))

#Example 3          
start_date = datetime(2020,12,17)
days_month_list = [5,10]
print(find_condition_date(start_date,days_month_list))

#Example 4
start_date = datetime(2021,2,17)
days_month_list = [5,10,31]
print(find_condition_date(start_date,days_month_list))

#Example 5
start_date = datetime(2021,4,17)
days_month_list = [31]
print(find_condition_date(start_date,days_month_list))
  

Приведенный выше код, похоже, работает так, как ожидалось.

Ответ №1:

Сначала извлеките день из start_date

Затем отсортируйте дни месяца и выполните итерацию по отсортированному массиву, чтобы найти первое значение, которое больше начальной даты

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

1. но если большего значения нет, я должен увеличить месяц

2. проверьте примеры, иногда месяц и год также меняются

3. Если нет подходящего дня (как в вашем последнем примере), вы можете проверить его с помощью datetime модуля и увеличить месяц и повторить процесс, или вы могли бы сначала извлечь год и месяц в качестве отправной точки

4. Любое особое условие, когда месяц в start_datetime равен февралю?

5. Хорошо, это моя первая мысль об этой проблеме. Я приму ваш ответ (возможно, я предпочел больше, если в нем есть какой-то код на python… В любом случае…

Ответ №2:

Перебираем доступные дни, пока не найдем следующую ближайшую допустимую дату (увеличивая месяц / год по мере необходимости):

 from datetime import date


def valid_date(y, m, d):
    try:
        date(y, m, d)
        return True
    except ValueError:
        return False


def find_next_date(start_date, days_of_month):
    current_year, current_month, current_day = map(int, start_date.split('-'))
    while True:
        for day in days_of_month:
            if day >= current_day and valid_date(current_year, current_month, day):
                return f'{current_year}-{current_month:02}-{day:02}'

        current_month  = 1
        current_day = 1
        if current_month > 12:
            current_month = 1
            current_year  = 1


assert find_next_date('2020-11-17', [5, 10, 20]) == '2020-11-20'
assert find_next_date('2020-11-17', [5, 10]) == '2020-12-05'
assert find_next_date('2020-12-17', [5, 10]) == '2021-01-05'
assert find_next_date('2021-02-17', [5, 10, 31]) == '2021-03-05'
assert find_next_date('2021-04-17', [31]) == '2021-05-31'