代表性面试主题

如何用 JavaScript Temporal 正确处理跨时区预约?

编程题中等
Offer.cc 编辑团队发布 更新

题干

请设计一个跨时区预约功能:用户选择本地日期时间,系统需要在目标时区准确提醒并支持夏令时变化。请用 Temporal 说明类型选择、转换、持久化和异常处理。

题目与背景

一个全球预约系统接收“纽约时间 2026-11-01 01:30”的输入,并在参与者所在时区展示和提醒。请使用 JavaScript Temporal 设计从输入、时区解析、持久化到展示的流程,处理夏令时重复或不存在的本地时间。不要用一个裸字符串或 Date 对象混淆日期、时间和时区语义。

面试官考察什么

重点是区分 Temporal.InstantTemporal.ZonedDateTimeTemporal.PlainDateTimeTemporal.PlainDate,理解 IANA 时区规则、DST 歧义、精度与序列化。优秀答案会说明业务日历日期不能直接转成 UTC 瞬时点,以及如何固定日历系统。

先问清楚的澄清问题

输入语义

确认用户输入是“某时区的墙上时间”还是已经确定的瞬时点,时区来自事件、组织还是浏览器。缺少时区就不能可靠地解释本地时间。

DST 歧义策略

确认不存在或重复时间时是拒绝、选择较早、选择较晚还是让用户确认。默认策略必须写入产品契约,不能由运行时偶然决定。

持久化需求

确认提醒是否代表一次绝对瞬时事件,还是每年在当地日期重复。一次性预约与生日类规则需要不同的 Temporal 类型。

30 秒回答框架

“先把用户输入保留为 PlainDateTime 与明确的 IANA 时区,再按产品策略转换成 ZonedDateTimeInstant。一次性提醒持久化 Instant,展示时用参与者时区重新转换;重复日历事件持久化日期、时间、时区和日历规则。对 DST 缺失或重复时间显式拒绝或选择策略,并保存原始语义,避免用 Date 的隐式本地时区解析。”

深入解答步骤

第一步:选择正确类型

PlainDate 表示没有时区的日历日期,PlainDateTime 表示没有时区的墙上时间,ZonedDateTime 绑定 IANA 时区,Instant 表示时间线上的单一点。先判断业务语义再选类型。

第二步:解析并绑定时区

解析用户输入得到 PlainDateTime,从受信任配置取得时区标识,再组合成 ZonedDateTime。禁止把浏览器默认时区或服务器时区偷偷当作事件时区。

第三步:处理 DST 变化

春季跳时会产生不存在的本地时间,秋季回拨会产生重复的本地时间。使用明确的 disambiguation 策略,例如拒绝并让用户重选,或在需求允许时选择 earlier/later;把选择记录在预约数据中。

第四步:转换为提醒瞬时点

一次性预约从 ZonedDateTime 取得 Instant 并以标准化字符串保存。调度器按 Instant 触发,展示层再根据查看者时区转换,而不是重新解释原始墙上时间。

第五步:保存重复事件语义

每年某地 09:00 的事件不能只保存一个 UTC 偏移,因为 DST 会改变偏移。保存 PlainDatePlainTime、IANA 时区和日历系统,每次发生时重新解析成当年的 ZonedDateTime

第六步:定义精度与日历

明确是否需要毫秒、微秒或纳秒精度,序列化时不要截断导致排序错误。跨日历业务要保存 calendar 标识,不能把用户日历日期直接当成 ISO 公历日期。

第七步:测试边界

覆盖 DST 跳时和回拨、跨年、闰日、时区数据库更新、不同语言环境和序列化往返。测试应断言瞬时点、当地展示和重复规则分别正确,而不只比较字符串。

高质量示例回答

我会将输入解析为 PlainDateTime,要求事件携带 IANA 时区,再按明确的 DST 歧义策略组合成 ZonedDateTime。一次性提醒持久化 Instant,展示时按查看者时区转换;重复事件持久化当地日期、时间、时区和日历规则,每次生成新的瞬时点。测试覆盖缺失/重复时间、闰日、时区库更新和序列化精度,避免 Date 的隐式时区行为。

常见错误

  • 错误:PlainDateTime 直接当 UTC。→ 原因: 它没有时区语义。→ 改进: 先绑定明确的 IANA 时区。
  • 错误: 每年重复事件只保存 UTC 偏移。→ 原因: DST 会改变当地偏移。→ 改进: 保存当地时间和时区规则。
  • 错误: 忽略秋季回拨的重复时间。→ 原因: 一个墙上时间对应两个瞬时点。→ 改进: 拒绝或显式选择 earlier/later。
  • 错误: 只用字符串比较验证结果。→ 原因: 字符串无法证明瞬时点和日历语义。→ 改进: 分别断言 Instant、ZonedDateTime 和重复规则。

追问与回答

追问 1:什么时候应该持久化 Instant?

当事件代表时间线上的一次绝对发生,例如发送提醒或记录付款。查看者时区只影响展示,不应改变该瞬时点。

追问 2:为什么生日不能保存成 Instant?

生日表达的是当地日历日期,通常不代表某个全球同时发生的瞬时点。保存日期、时区和日历规则,发生时再计算 Instant。

追问 3:时区数据库更新会影响已保存预约吗?

会。未来本地时间的规则可能变化,因此保存原始时区和语义,并记录规则版本或在重新计算时采用明确的业务策略。

追问 4:Temporal 能否自动决定 DST 歧义?

API 可以提供 disambiguation 选项,但产品仍需决定拒绝、取早、取晚或兼容。不能把默认选项当成业务共识。

公开来源

同类题目

相关面试工具

用 Screenshot 处理算法题

截图题目后,按顺序看约束、解法、代码、边界条件和复杂度。

查看工具