【问题标题】:Python check two dates inside date rangePython检查日期范围内的两个日期
【发布时间】:2020-01-14 17:36:52
【问题描述】:

我需要检查这两个日期,不在列表中的任何日期范围内。

我想知道用户是否可以在日期(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'] 的范围内)?

【问题讨论】:

  • 我想知道用户是否可以在日期(两个变量)或已经预订的日期(在 date_ranges 中)进行登记
  • 你能澄清一下 check_range_true = ['2020-02-02', '2021-02-04'] 是否应该返回 true 吗?
  • 这能解决您的问题吗?
  • 我认为不,有时会得到错误的结果

标签: python datetime compare conditional-statements


【解决方案1】:

你要做的是用 (start

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

【讨论】:

  • 为什么要做这一步 - date_ranges = date_ranges[1:-1] ?
  • 仅提取可用日期。将此['2020-1-12', '2020-1-13'], ['2020-1-14', '2020-1-15'] 转换为此['2020-1-13','2020-1-14']
  • 它似乎无法正常工作,例如 - yadi.sk/i/uMEwOjyF66LOCw 您的代码告诉我可以预订 24.01 到 26.01 的日期,但 25.01 已经预订,这意味着我无法在此范围内预订。跨度>
【解决方案2】:

如果我理解正确,您想检查给定的日期范围(例如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

我希望这能回答您的问题。当然这只是一个草稿,肯定有一些改进的余地,但应该是给定问题的有效解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    相关资源
    最近更新 更多