数据库sql中判断时间冲突
数据库现有数据其中两列: s - 开始时间, e - 结束时间. 在新插入数据s', e'之前需要判断两个时间之间是否有重合
因为使用mybatis-plus的缘故, 结论都使用s或e在符号前面.
1. s < e
比如yyyy-MM-dd HH:mm:ss
格式的数据, 多用于判断预约时间和每日排班冲突.
对于冲突的情况使用列举法有
情况1: s' < e' < s < e (新时间段在已有时间左边, 不包含)- 情况2: s' < s < e' < e (新时间段和已有时间左边有交集)
- 情况3: s < s' < e' < e (新时间段在已有时间内, 被包含关系, 也即在已有时间段内部)
- 情况4: s < s' < e < e' (新时间段和已有时间右边有交集)
- 情况5: s' < s < e < e' (新时间和已有时间是是包含关系, 也即新时间段在已有时间段外部)
情况6: s < e < s' < e' (新时间段在已有时间右边, 不包含)
除去情况1和6的不包含, 可以得到当s < e' 并且 e > s'时候两个时间端肯定有交集, 也即冲突.
2. 存在s > e
比如HH:mm:ss
格式的, 多用于固定早中晚班定义 / 营业时间等周期性活动的时间冲突判断.
2.1 分段比较
- 在保存s和e时候, 如果是跨天的拆分成s,24,0,e; 不跨天的话使用s,e,s,e, 对应字段
s,e,s1,e1
- 对于s'和e'来说也是同上, 拆分出
s',e',s1',e1'
- 分别比较
s,e和s',e'
与s1,e1和s1',e1'
, 两个条件使用或者连接, 也即: ((s < e' 并且 e > s') 或者 (s1 < e1' 并且 e1 > s1'))
2.2 代码
// s', e' String startTime = "22:00:00", endTime = "24:00:00"; // s1', e1' String startTime1 = "00:00:00", endTime1 = "03:00:00"; // ((s < e' 并且 e > s') || (s1 < e1' 并且 e1 > s1')) configService.lambdaQuery() .and(q -> q .lt(BaseTimeConfig::getS, endTime) .gt(BaseTimeConfig::getE, startTime)) .or(q -> q .lt(BaseTimeConfig::getS1, endTime1) .gt(BaseTimeConfig::getE1, startTime1)) .list();
3. s'=e'
也即当前时间是否在已存在的时间范围内
String now = "23:38:34"; // String now = "03:12:54"; // ((s < e' 并且 e > s') || (s1 < e1' 并且 e1 > s1')) // 其中 s' = e' = sl' = el' = now // 如果不存在s > e的情况, 就不需要截取了 configService.lambdaQuery() .and(q -> q .lt(BaseTimeConfig::getS, now) .gt(BaseTimeConfig::getE, now)) .or(q -> q .lt(BaseTimeConfig::getS1, now) .gt(BaseTimeConfig::getE1, now)) .list();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下