两个时间区间在各自的开始时间都早于另一个区间的结束时间时,就会重叠。这个判断也涵盖完全包含的情况。下面介绍如何在 Mac 版 Numbers 中应用此规则,以比较发布时段、验证日期并处理端点相接的情况。

本工作流程适用于在电子表格中规划发布时段的场景。以下所有日期和标签均为虚构内容。你将逐行比较两段时段,并获得清晰的结果,无需编写程序。

什么情况算重叠?

首先,确定区间是否包含其结束时刻。本文使用包含起始时刻、不包含结束时刻的区间,写作 [start, end)。从 09:00 到 12:00 的时段包含其起始时刻,并在中午结束。因此,从 12:00 开始的另一时段不会与它重叠。这与 iCalendar 中的事件惯例一致:DTSTART 表示包含,DTEND 表示不包含。RFC 5545,第 3.6.1 节。

对于两个有效且长度大于零的区间,完整的重叠判断规则是:

A.start < B.end AND B.start < A.end

原理很简单。如果 A 在 B 开始之前或恰好在 B 开始时结束,或者 B 在 A 开始之前或恰好在 A 开始时结束,那么这两个时段彼此分开。如果这两种分开条件都不成立,它们就有共同的时间。这也解释了为什么完全包含的情况不需要额外的重叠条件。

假设 A 从 09:00 持续到 12:00。如果 B 从 08:00 持续到 13:00,B 的两个端点都不在 A 内,但 B 包含了整个 A。如果只检查 B 的开始或结束是否落在 A 内,就会漏掉这种情况。两项比较的规则可以正确识别它。

将这组虚构测试数据放在电子表格旁边。以下每个时间都属于 2026 年 11 月 10 日,并使用相同的时间基准。

A 时段 B 时段 预期结果 原因
09:00–12:00 11:00–13:00 重叠 部分交叉
09:00–12:00 10:00–11:00 重叠 A 包含 B
09:00–12:00 08:00–13:00 重叠 B 包含 A
09:00–12:00 09:00–12:00 重叠 时段完全相同
09:00–12:00 12:00–13:00 不重叠 仅端点相接
09:00–12:00 13:00–14:00 不重叠 两个时段之间有间隔

在 Numbers 中设置可比较的日期和时间

对于有具体时间的发布时段,请使用完整的日期和时间。单独的时钟时间无法区分今天早晨和明天早晨。Numbers 也会补齐缺失的部分:只输入时间时,会自动添加今天的日期。隐藏日期或时间只会改变显示方式,存储的值仍会参与计算。在 Mac 版 Numbers 中设置日期、货币等格式。

创建一个包含以下列的表格,并在第 1 行设置标题:

列 标题 用途
A 配对 用于标记比较的中性标签
B A 开始 第一个时段的起始时间
C A 结束 第一个时段不包含在内的结束时间
D B 开始 第二个时段的起始时间
E B 结束 第二个时段不包含在内的结束时间
F 输入检查 是否可以进行比较
G 重叠结果 比较结果

选择 B 到 E 列中的输入单元格。在“格式”侧边栏中选择“单元格”,然后将“数据格式”设为“日期与时间”。选择能同时显示日期和时间的格式。窗口底部的“智能单元格视图”可让你检查所选值中的日期和时间部分。Apple 的日期与时间格式说明。

要创建一个可重复的首个示例,请在 A2 中输入 Sample pair,然后在指定单元格中输入以下公式。这些公式会在 2026 年 11 月 10 日生成 A 的 09:00–12:00 时段和 B 的 10:00–11:00 时段。本例中的每个端点都按 UTC 处理;请在表格旁注明此约定。

单元格 公式
B2 =DATE(2026,11,10)+DURATION(0,0,9)
C2 =DATE(2026,11,10)+DURATION(0,0,12)
D2 =DATE(2026,11,10)+DURATION(0,0,10)
E2 =DATE(2026,11,10)+DURATION(0,0,11)

DATE 根据年、月、日生成日期,避免日期字符串产生歧义。DURATION 的前三个参数依次表示周、天和小时,因此 DURATION(0,0,9) 表示九小时。这些是电子表格公式,不是终端命令。DATE、DURATION。

要输入公式,请选中目标单元格,输入 =,再输入表达式并按下 Return。Numbers 支持比较单元格值,并显示布尔结果。如果你的设置使用逗号作为小数分隔符,请用分号代替逗号分隔函数参数。在 Mac 版 Numbers 中使用表格单元格的数据计算值、函数概览。

测试重叠前先验证时段

对于此任务,要求四个端点都是可识别的日期/时间值,并且结束时间严格晚于相应的开始时间。顺序颠倒的区间需要修正。长度为零的发布时段也需要单独决定如何处理,因为按照所选惯例,它不占用任何时间。

在 F2 中输入以下公式:

=IF(AND(ISDATE(B2),ISDATE(C2),ISDATE(D2),ISDATE(E2)),IF(AND(B2<C2,D2<E2),"Ready","Invalid window"),"Check dates")

外层检查用于确认每个端点都是日期值。内层检查用于确认两个时段的先后顺序。ISDATE 用于识别日期值,AND 要求其中所有条件都为真,而 IF 会选择相应的结果。ISDATE、AND、IF。

示例应返回 Ready。如果返回 Check dates,请检查输入单元格,不要把这一行当作互不相关的时段。如果返回 Invalid window,请检查端点是否相同、输入顺序是否颠倒,或是否漏填了第二天的日期。先让任何公式错误保持显示,直到你找到并修正其原因。

检测重叠,包括完全包含的情况

在 G2 中输入以下公式:

=IF(F2="Ready",IF(AND(B2<E2,D2<C2),"Overlap","No overlap"),"Check inputs")

对于有效行,这两项比较会直接实现重叠判断规则:B2 是 A 的开始时间,E2 是 B 的结束时间,D2 是 B 的开始时间,C2 是 A 的结束时间。只有两项比较都成立时,AND 才会返回真。Apple 的 AND 文档。

示例会返回 Overlap,因为 B 完全位于 A 内。将 D2 的小时改为 8,并将 E2 的小时改为 13;结果仍应为 Overlap,此时 B 包含 A。再将它们改为 12 和 13;结果应变为 No overlap。

使用前面的测试表检查其余情况。要进行更多比较,请在下一行输入另一组配对,并将 F 和 G 列的公式复制到该行。检查复制后的公式,确认引用已指向新行。

此布局会比较每一行中提供的两个时段。它不会自动将单独事件列表中的每个时段都与其他所有事件进行比较。对于较短的列表,请为每一组需要检查的不同配对各建一行,并避免重复反向配对。

确定哪个时段包含另一个时段

重叠与包含回答的是不同问题。如果你还需要知道 A 是否完全包含 B,请添加名为 A contains B 的 H 列,并输入:

=IF(F2="Ready",AND(B2<=D2,E2<=C2),"Check inputs")

要判断 B contains A,请添加 I 列并输入:

=IF(F2="Ready",AND(D2<=B2,C2<=E2),"Check inputs")

这些包含判断允许边界相同。因此,时段完全相同时,两列都会返回 TRUE。如果你的任务要求时段在两端都留有空隙,请将相关包含公式中的两个非严格比较都替换为严格比较。这是额外的编辑条件,不会改变重叠结果。

区分民用日期、时间点、时差和时区

应用公式前,先确定输入值的含义。像 2026-11-10 这样的民用日期表示一个日历日期,不指定时区。它适用于全天发布标签。TC39 的 Temporal.PlainDate API 明确将此类日期建模为独立于时区的值。Temporal.PlainDate。

时间点表示时间轴上的一个位置。像 +01:00 这样的时差表示某个时刻与 UTC 之间的差值。像 Europe/Paris 这样的命名时区则提供地区时间规则。这些信息各不相同:固定时差不包含命名时区中会变化的规则。Temporal.ZonedDateTime。

例如,虚构时间戳 2026-11-10T10:00:00+01:00 和 2026-11-10T09:00:00Z 表示同一时间点。如果只比较显示的小时,排序结果就会错。

以上电子表格公式会比较你输入的值;其中不包含任何命名时区转换步骤。对于源自不同时区的定时窗口,请先将每个端点转换为时间点,并以 UTC 表示所有端点。如果需要还原预期的当地日程,请单独保留原始时区信息。

要进行自动转换,文档中所述的 API 操作是使用时区构造 Temporal.ZonedDateTime,然后通过 toInstant() 进行转换。其 compare() 方法可比较精确时间。夏令时偏移切换期间,某个当地时间可能不存在或重复;此 API 提供了明确的消歧选项,包括 reject。导入可比较的值之前,请先解决此类歧义。Temporal.ZonedDateTime 转换、比较和消歧。

对于全天时段,请按民用日期处理。覆盖 11 月 10 日至 11 月 12 日(含首尾两天)的虚构发布时段可以表示为 [2026-11-10, 2026-11-13)。iCalendar 同样会将全天事件结束日之后的一天作为不包含在内的结束日期。在 Numbers 中,请使用 DATE 公式输入这些边界,以确保时间部分一致。RFC 5545 的多日事件示例。

处理边界情况,同时保持判断标准不变

跨夜区间的结束值需要填写第二天的日期。从 11 月 10 日 23:00 开始,到 11 月 11 日 01:00 结束的时段是有效的。如果两个端点都填写 11 月 10 日,时间顺序就会颠倒。请修正日期,不要自动交换值,因为交换值可能掩盖输入错误。

如果你要处理的特定任务应将端点相接视为重叠,请在 G2 公式中使用 AND(B2<=E2,D2<=C2)。除非你已另行定义点事件的处理方式,否则请保留长度大于零的输入检查。此更改会改变边界规则,应在表格旁注明。

使用原生 Mac API 时,这项规则同样重要。Apple 将 Foundation 的 DateInterval 记录为闭区间,包含两个端点,并允许持续时间为零。它提供 intersects 和 intersection(with:),但其闭区间模型与本文采用的 iCalendar 惯例不同。要判断持续时间大于零的日历时段是否重叠,请使用明确的严格端点判断,而不要假定某个 API 的相交规则符合你的任务。DateInterval。

在依赖比较结果之前,请检查三件事:每个端点都有正确的日期和时间基准;两个时段的长度都大于零;端点相接的示例会产生你选择的结果。明确这些决定后,同样的两项比较即可处理部分重叠、完全包含和时段相同的情况。

来源