You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python结合JSON检测预订时间是否已被占用并提供备选建议

预订时间检测问题修正

需求说明

需要实现以下功能:

  • 检查用户选择的时间在JSON预订数据中是否可用
  • 若该时间已被预订,推荐下一个可用时间并询问用户是否预订
  • 用户选择“否”则返回选择时间的步骤

现有预订数据

CSV格式

name, start_time, end_time
Michał Najman, 23.03.2023 14:00, 23.03.2023 15:00
Marcin Wiśniewski, 23.03.2023 17:00, 23.03.2023 18:00
Tadeusz Stockinger, 24.03.2023 11:00, 24.03.2023 12:30
Robert Brzozowski, 24.03.2023 12:30, 24.03.2023 14:00
Norman Dudziuk, 24.03.2023 16:30, 24.03.2023 17:00
Klaus Sevkovic, 25.03.2023 14:00, 25.03.2023 14:30
Paweł Gulczyński, 26.03.2023 12:00, 26.03.2023 13:30
Mieczysław Okniński, 26.03.2023 13:30, 26.03.2023 14:00

JSON格式

{"23.03": [{
  "name": "Michał Najman",
  "start_time": "14:00",
  "end_time": "15:00"
},
{"name": "Marcin Wiśniewski",
  "start_time": "17:00",
  "end_time": "18:00"
}],
  "24.03": [{
  "name": "Tadeusz Stockinger",
  "start_time": "11:00",
  "end_time": "12:30"
},
{"name": "Robert Brzozowski",
  "start_time": "12:30",
  "end_time": "14:00"
},
  {"name": "Norman Dudziuk",
  "start_time": "16:30",
  "end_time": "17:00"
}],
    "25.03": [{
  "name": "Klaus Sevkovic",
  "start_time": "14:00",
  "end_time": "14:30"
}],
    "26.03": [{
  "name": "Paweł Gulczyński",
  "start_time": "12:00",
  "end_time": "13:30"
},
{"name": "Mieczysław Okniński",
  "start_time": "13:30",
  "end_time": "14:00"
}],
    "27.03": [],
    "28.03": [],
    "29.03": [],
    "30.03": []
}

原代码及问题

原代码

import json


class Make_aReservation:
    # print('$ Make a reservation ')
    # name = input("What's your Name?\n")
    book = input("When would you like to book? {DD.MM.YYYY HH:MM}\n")

    def __init__(self):
        self.filename = '23.03-30.03.json'

    def file_to_text(self):
        with open(self.filename, "r") as file_opened:
            text = json.load(file_opened)
            return text

    def reservation(self):
        # print(self.file_to_text())
        if self.book[:5] in self.file_to_text():
            # print(self.file_to_text()[self.book[:5]])
            # print(self.file_to_text()[self.book[:5]])
            for i in self.file_to_text()[self.book[:5]]:
                print(i)
                print(self.book[11:16])
                if self.book[11:16] in i['end_time']:
                    print(True)
                else:
                    print(False)


make_aReservation = Make_aReservation()
print(make_aReservation.reservation())

原代码运行结果

When would you like to book? {DD.MM.YYYY HH:MM}
23.03.2023 15:00
{'name': 'Michał Najman', 'start_time': '14:00', 'end_time': '15:00'}
15:00
True
{'name': 'Marcin Wiśniewski', 'start_time': '17:00', 'end_time': '18:00'}
15:00
False
None

Process finished with exit code 0

原代码问题

  1. 冲突检测逻辑错误:仅检查用户输入时间是否等于某个预订的结束时间,无法判断时间段是否重叠(比如用户预订14:30-15:30,会和14:00-15:00的预订冲突,但原代码检测不出来)
  2. 类结构不合理:book作为类属性会在类加载时就触发输入,不符合面向对象设计规范
  3. 未使用时间对象比较:直接用字符串比较时间,容易出现逻辑漏洞(比如"10:00"和"9:00"的字符串比较结果不正确)

修正后的代码

import json
from datetime import datetime, timedelta


class ReservationSystem:
    def __init__(self, filename='23.03-30.03.json'):
        self.filename = filename
        self.bookings = self._load_bookings()
        # 默认预订时长1小时,可根据需求调整
        self.default_duration = timedelta(hours=1)

    def _load_bookings(self):
        """加载JSON中的预订数据"""
        with open(self.filename, 'r', encoding='utf-8') as f:
            return json.load(f)

    def _parse_user_time(self, user_input):
        """解析用户输入的时间为datetime对象"""
        try:
            return datetime.strptime(user_input, "%d.%m.%Y %H:%M")
        except ValueError:
            print("输入格式错误,请按照DD.MM.YYYY HH:MM格式输入")
            return None

    def _is_time_available(self, user_start, date_key):
        """检查用户预订时间段是否可用"""
        user_end = user_start + self.default_duration
        # 获取当天的所有预订
        day_bookings = self.bookings.get(date_key, [])
        for booking in day_bookings:
            # 解析预订的时间为datetime对象
            booking_start = datetime.strptime(f"{date_key}.2023 {booking['start_time']}", "%d.%m.%Y %H:%M")
            booking_end = datetime.strptime(f"{date_key}.2023 {booking['end_time']}", "%d.%m.%Y %H:%M")
            # 检查时间段是否重叠:用户开始时间 < 预订结束时间,且用户结束时间 > 预订开始时间
            if user_start < booking_end and user_end > booking_start:
                return False, booking_end
        return True, None

    def _get_next_available_time(self, date_key):
        """获取当天的下一个可用时间"""
        day_bookings = self.bookings.get(date_key, [])
        if not day_bookings:
            # 当天无预订,默认最早可用时间为09:00
            return datetime.strptime(f"{date_key}.2023 09:00", "%d.%m.%Y %H:%M")
        # 按结束时间排序预订
        sorted_bookings = sorted(day_bookings, key=lambda x: x['end_time'])
        last_end_time = sorted_bookings[-1]['end_time']
        next_start = datetime.strptime(f"{date_key}.2023 {last_end_time}", "%d.%m.%Y %H:%M")
        # 检查下一个时间是否在合理时间段内(比如到18:00)
        if next_start.time() <= datetime.strptime("18:00", "%H:%M").time():
            return next_start
        else:
            print("当天剩余时间已无可用时段,请选择其他日期")
            return None

    def start(self):
        """启动预订流程"""
        while True:
            user_input = input("When would you like to book? {DD.MM.YYYY HH:MM}\n")
            user_start = self._parse_user_time(user_input)
            if not user_start:
                continue
            # 提取日期键(DD.MM)
            date_key = user_start.strftime("%d.%m")
            if date_key not in self.bookings:
                print("该日期不在可预订范围内,请选择23.03-30.03之间的日期")
                continue

            # 检查时间是否可用
            available, conflicting_end = self._is_time_available(user_start, date_key)
            if available:
                confirm = input(f"时间{user_start.strftime('%d.%m.%Y %H:%M')}可用,是否确认预订?(是/否)\n")
                if confirm.lower() in ['是', 'y', 'yes']:
                    # 这里可以添加保存预订到JSON的逻辑
                    print("预订成功!")
                    break
                else:
                    print("返回时间选择步骤")
                    continue
            else:
                print(f"时间{user_start.strftime('%d.%m.%Y %H:%M')}已被预订")
                next_time = self._get_next_available_time(date_key)
                if next_time:
                    confirm = input(f"推荐下一个可用时间:{next_time.strftime('%d.%m.%Y %H:%M')},是否预订?(是/否)\n")
                    if confirm.lower() in ['是', 'y', 'yes']:
                        # 添加保存逻辑
                        print("预订成功!")
                        break
                    else:
                        print("返回时间选择步骤")
                        continue
                else:
                    continue


if __name__ == "__main__":
    system = ReservationSystem()
    system.start()

代码说明

  1. 重构类结构:将输入逻辑移到start方法中,类初始化时仅加载预订数据,符合面向对象设计
  2. 时间解析与比较:使用datetime模块解析时间字符串为可比较的对象,避免字符串比较的漏洞
  3. 正确的冲突检测:通过时间段重叠逻辑判断是否可用,覆盖所有可能的冲突场景
  4. 下一个可用时间推荐:根据当天最后一个预订的结束时间推荐,若当天无预订则默认09:00
  5. 完整流程控制:实现了用户输入验证、确认预订、返回重选的完整逻辑

内容的提问来源于stack exchange,提问作者Marcin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 16:44:57