如何查看给定日期是否在其他两个日期时间对象之间?

How to see if the given date is between two other datetimes objects?

我想查看用户预订日期是否在数据库中的其他两个日期时间对象之间。

我的 table start_time 和 end_time 有两个不同的时间,所以 start_time 表示何时开始预订, end_time 表示何时它会结束,这是代码:

def parse_time(time):
    tdateime = str(time)
    date = parse(tdateime)
    return date

start = '2017-08-23 11:00:00'
end = '2017-08-23 11:50:00'

p1 = parse_time(start)
p2 = parse_time(end)
p3 = 'the date to be checked'

check_is_free = Appointment.query.filter(Appointment.start_time == p1).filter(Appointment.end_time == p2).first()
original_start_date = check_is_free.start_time
original_end_date = check_is_free.end_time
if check_is_free:
    if original_start_date <= p3 <= check_is_free.end_time:
        error = 'already reserved.'
        return jsonify({'occupied':error})

这里结束的是服务时间段,比如预约从11:00开始,服务时间是50分钟,timedelta会在开始时间加上这50分钟,所以最后的结果就是11:50这段时间一定很忙,不能在这段时间出书

如果用户想在今天 '11:30:00' 预订服务,它应该给他错误消息,即 already reserved,但如何才能我得到了第三个日期??,事实上,我正在使用 bootstrap-datepicker 选择日期时间,我只有一个字段来选择开始日期和时间。

我尝试通过解析开始时间并将其值放入变量 p3 来进行一些更改,但在这里它会忽略上面的所有代码和约会将被接受,因为 p3start 相同,如果开始时间匹配 check_is_free 它会给我预订的服务,这里会出现错误,但如果我将开始时间更改一分钟,check_is_free 将 return a None ,这意味着约会将被接受,但我不会。

您能否过滤以查找是否有任何 Appointment 与用户所需的约会 window 重叠?我的意思是:

# User's desired appointment window is start_time to end_time 

# an appointment is not overlapping, if
# - the end_time is before an existing start time, or
# - the start_time is after an existing end time
overlapping = session.query(Appointment).filter(
    not_(
        or_(Appointment.start_time > end_time,
             Appointment.end_time < start_time)))

这是一个完整的工作示例,您可以尝试一下:

from datetime import datetime, timedelta
from sqlalchemy import create_engine, Column, DateTime, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import or_, not_

engine = create_engine('sqlite:///:memory:')
Session = sessionmaker(bind=engine)
Base = declarative_base()

class Appointment(Base):
    __tablename__ = 'appointments'

    id = Column(Integer, primary_key=True)
    start_time = Column(DateTime, nullable=False)
    end_time = Column(DateTime, nullable=False)

Base.metadata.create_all(engine)

session = Session()
existing_appointment = Appointment(id=1,
                                   start_time=datetime(2017,8,23,11,0),
                                   end_time=datetime(2017,8,23,11,50))
session.add(existing_appointment)
session.commit()

def check_appointment(start_time):
    end_time = start_time + timedelta(minutes=20)
    overlapping = session.query(Appointment).filter(
        not_(
            or_(Appointment.start_time > end_time,
                Appointment.end_time < start_time)))
    return not overlapping.count()

print('check 2017-08-23 11:30 (should be False): {}'.format(check_appointment(datetime(2017,8,23,11,30))))
print('check 2017-08-23 10:30 (should be True): {}'.format(check_appointment(datetime(2017,8,23,10,30))))