Python отметьте две даты в диапазоне дат - PullRequest
0 голосов
/ 14 января 2020

Мне нужно проверить, что две даты, а не в каком-либо диапазоне дат в списке.

Я хочу узнать, может ли пользователь зарегистрироваться в датах (check_range_true - может, check_range_false - не может) или эти даты уже забронированы (в date_ranges)

У меня диапазон выглядит так:

date_ranges = [
    ['2020-1-12', '2020-1-13'],
    ['2020-1-14', '2020-1-15'],
    ['2020-1-15', '2020-1-16'],
    ['2020-1-16', '2020-1-18'],
    ['2020-1-18', '2020-1-19'],
    ['2020-1-21', '2020-1-23'],
    ['2020-1-23', '2020-1-27'],
    ['2020-1-30', '2020-2-1'],
    ['2020-2-5', '2020-2-7'],
    ['2020-2-7', '2020-2-9'],
    ['2020-2-9', '2020-2-11'],
    ['2020-2-14', '2020-2-18'],
    ['2020-2-20', '2020-2-26'],
    ['2020-3-26', '2020-3-30'],
    ['2020-5-29', '2020-5-30'],
    ['2020-10-10', '2021-1-15']
]

И две даты (например)

check_range_true = ['2020-02-02', '2020-02-04']
check_range_false = ['2020-02-02', '2020-02-05']

Я знаю, как проверить один дата в диапазоне, но не понимаю, как ее решить с двумя датами.

Как лучше всего проверить эти даты в диапазоне и получить результаты, True для первой переменной (из-за 2020-02-02, 2020-02-04 не диапазон «касания») и False для второй переменной (поскольку 2020-02-05 находится в диапазоне ['2020-2-5', '2020-2-7'])?

Ответы [ 2 ]

1 голос
/ 14 января 2020

Что вам нужно сделать, это проверить даты с (начало <первая_дата <конец) и (начало <конечная_дата <конец) logi c</p>

date_ranges = [
    ['2020-1-12', '2020-1-13'],
    ['2020-1-14', '2020-1-15'],
    ['2020-1-15', '2020-1-16'],
    ['2020-1-16', '2020-1-18'],
    ['2020-1-18', '2020-1-19'],
    ['2020-1-21', '2020-1-23'],
    ['2020-1-23', '2020-1-27'],
    ['2020-1-30', '2020-2-1'],
    ['2020-2-5', '2020-2-7'],
    ['2020-2-7', '2020-2-9'],
    ['2020-2-9', '2020-2-11'],
    ['2020-2-14', '2020-2-18'],
    ['2020-2-20', '2020-2-26'],
    ['2020-3-26', '2020-3-30'],
    ['2020-5-29', '2020-5-30'],
    ['2020-10-10', '2021-1-15']
]
#convert to a flat list
date_ranges = [k for i in date_ranges for k in i]
#truncate the start and the end value    
date_ranges = date_ranges[1:-1]
#convert values to datetime
import datetime
date_ranges = [datetime.datetime.strptime(i, '%Y-%m-%d') for i in date_ranges]
#create available time slots
date_ranges = [[date_ranges[i],date_ranges[i+1]] for i in range(0,len(date_ranges),2)]

#convert the check date to date time
check_range = ['2020-02-02', '2020-02-04']
check_range = [datetime.datetime.strptime(i, '%Y-%m-%d') for i in check_range]

# apply the logic of start < date < end twice
any([(i[0] < check_range[0] < i[1]) and (i[0] < check_range[1] < i[1]) for i in date_ranges])
True

check_range = ['2020-02-02', '2020-02-05']
check_range = [datetime.datetime.strptime(i, '%Y-%m-%d') for i in check_range]

any([(i[0] < check_range[0] < i[1]) and (i[0] < check_range[1] < i[1]) for i in date_ranges])

False
0 голосов
/ 15 января 2020

Если я правильно понимаю, вы хотите проверить, пересекается ли данный диапазон дат (например, check_range_true) (или нет) с любым другим диапазоном дат, указанным в списке. Чтобы достичь этого, я сначала преобразовал бы строковые значения в соответствующие datetime объекты для более простого сравнения дат. Это может быть достигнуто с помощью понимания списка и strptime:

from datetime import datetime

booked_date_ranges = [
    [datetime.strptime(start_date, '%Y-%m-%d'), datetime.strptime(end_date, '%Y-%m-%d')]
    for start_date, end_date in date_ranges
]

Затем я создам функцию, которая будет проверять, перекрывается ли указанный диапазон дат (состоящий из даты начала и окончания) с любым диапазоном дат из ранее указанного списка. Необходимо проверить, находится ли дата начала между диапазоном дат или датой окончания между диапазонами дат. Это будет примерно так:

def dates_overlap(date_range_to_check, booked_date_ranges):
    dates = [datetime.strptime(date, '%Y-%m-%d') for date in date_range_to_check]
    return any(
        (start_date <= dates[0] and dates[0] <= end_date) or (start_date <= dates[1] and dates[1] <= end_date)
        for start_date, end_date in booked_date_ranges
    )

Тогда, если вы хотите проверить, не перекрывается ли данный диапазон дат, вы можете просто использовать функцию dates_overlap и отменить результат:

>>> not dates_overlap(check_range_false, booked_date_ranges)
False
>>> not dates_overlap(check_range_true, booked_date_ranges)
True

Надеюсь, это ответит на ваш вопрос. Конечно, это всего лишь черновик, и определенно есть место для улучшения, но оно должно быть рабочим решением данной проблемы.

...