设计不重叠的日期时间事件

Posted

技术标签:

【中文标题】设计不重叠的日期时间事件【英文标题】:Designing non-overlapping date-time events 【发布时间】:2013-04-29 09:16:40 【问题描述】:

我有以下问题:

事件有“开始”和“结束”时间和数量。我对两者都使用 mysql DATETIME。

现在,如果我有一个“没有重叠事件”的约束,我需要进行一些检查等,但是如何设计呢?用户只需要 5 分钟左右的精度,但我想用几秒钟来计算,因为那是“更简单”/“更干净”

如果我有一个以“YYYY-MM-DD 12:00:00”-“YYYY-MM-DD 14:00:00”为起点的事件 (A)

还有一个

(B) "YYYY-MM-DD 14:00:00"-"YYYY-MM-DD 16:15:00" -> 它们不重叠,即使它们都包含 14:00:00。

为了确定它们确实不重叠,我应该使用

A.end

或者

A.end

第一个是最简单的,但是如果我有很多不同的事件并且需要检查我没有“超额预订”,即事件的单个金额不超过总金额,它会错过任何重叠(例如:如果每个活动都是预订多人的餐桌,我在任何给定时间都不能超过餐桌的总数)

【问题讨论】:

【参考方案1】:

在处理日期时间范围时,您使用的范围在开始时包含在内,而在结束时不包含在内,这是很常见的。例如:

(using ISO8601 formatting)

Start                  End
2013-04-29T01:00:00Z - 2013-04-29T02:00:00Z
2013-04-29T02:00:00Z - 2013-04-29T03:00:00Z

当值小于或等于开始且大于(但不等于)结束时,值在范围内。在上面的示例中,02:00 属于第二个范围,而不是第一个。换句话说:

Start <= value < End 

或者等价的,

Start <= value  AND  End > value

在数学中,使用Interval Notation,这称为“半开”区间。

[Start, End)

这总是比使用像01:59:59 这样的值更好的方法。考虑一下我是否要减去End - Start 以获得持续时间。我希望答案是 1 小时,而不是 59 分 59 秒。

大多数示例使用术语Start/End,但有时您会看到Begin/EndStart/Stop。就个人而言,我认为当你有一个包含/排除范围时使用的最佳术语集是Start/Until。它的另一个优点是两个术语都是 5 个字符,按字母顺序排列,并明确表示结束日期是唯一的。

此外,当您谈论不同的事件时,您应该将您的时间记录为 UTC,以防止时区混淆。这对于本地应用程序甚至很重要,因为许多时区会经历夏令时转换。您不希望在数据库中记录的值不明确。在 MySQL 中,您可以使用 TIMESTAMP 数据类型来确保将值存储为 UTC,或者如果您可以确保在应用程序代码中使用 UTC 值,则可以使用 DATETIME 数据类型。

【讨论】:

始终使用

以上是关于设计不重叠的日期时间事件的主要内容,如果未能解决你的问题,请参考以下文章

查找不同行中日期时间间隔的重叠?

Office 365 API为整天事件返回错误的开始和结束日期时间

PHP:选择时间范围重叠日期的重叠日期时间范围

快速解析 JSON 数组,对其进行排序并找到重叠的日期

查找时间范围以限制日历中同一时间发生的事件。 (django)

Impala SQL:合并具有重叠日期的行。不支持 WHERE EXISTS 和递归 CTE