我真的应该在 utc 中保存 table 预订时间吗?

Should I really save the table booking time in utc?

这可能是一个愚蠢的问题,我提前道歉,但考虑到业务环境,我是否真的需要在数据库中保存 table 预订时间的 utc 并担心将其转换为本地Web 客户端上的时间?

预订将始终针对特定位置 (geographic/city) 进行,因此无论当前与 utc 的时间偏移是多少(dst 与否等),预订时间为 3:00 pm 是该位置下午 3 点的预订时间,无论是未来还是过去。 这不是将在网上举行的活动,而是餐厅的现场活动。

我觉得即使我们开始在另一个国家预订,比方说西班牙,时区明显不同,这也是正确的。 仅仅因为伦敦的 3:00 与西班牙的 3:0 时间不同(以 utc 为单位)对系统来说并不重要..?

我是不是漏掉了一些很明显的东西? 我能不能简单地忽略处理不同的时区而只是将时间保存在 db w/o 偏移量中(假设所有时间都是本地时间,本地时间)?

我会在这里给出一个可能有点不受欢迎的意见,并说如果你确定你正在编写一个只会处理单个预订的应用程序,你不需要担心时区地点。您可以将服务器的 and/or 数据库的时区设置为该位置的时区,然后忘记它。

这里的一个警告是该时区是否受夏令时制约。在这种情况下,我会建议以 UTC 格式存储预订时间,并在必要时转换为该位置的时区;否则,当 DST 转换发生时,您的预订可能会减少一个小时。

总的来说,我认为以 UTC 格式存储时间是最佳做法,因为您知道它们始终是正确的,但我确实理解进行时区转换是一件痛苦的事情,在某些情况下可能并不值得付出努力申请。

鉴于你说:

... but given the business context, should I really need to be saving the table booking time in utc in the database and worry about converting it to local time on the web client?

... This is not an event that will happen online, its an in-person event for a restaurant.

您应该在这个用例中使用 UTC。您不是在记录某事发生的绝对时间点(现在或过去),而是在捕捉关于未来事件预计发生的时间和地点的意图

  • 输入预订日期和时间时,客户提供意图的“时间”部分。他们根据餐厅的当地时区提供。将其转换为 UTC 或其他一些时区可能会失去该意图。

    • 假设这是单次预订(不是重复规则),那么在 .NET 中,您可以为此使用 DateTime 类型,其 Kind 属性 设置为DateTimeKind.Unspecified(在很多情况下这是默认值)。
  • 意图的“位置”部分由您在设置系统或添加新餐厅位置时提供。最好在您的系统中为每个餐厅的设置或记录保留一个时区标识符,而不是暗示它。

    • 在 .NET 中,您应该使用与 TimeZoneInfo object 的 Id 属性 对应的字符串值。这是 IANA 时区 ID(例如 "Europe/London")或 Windows 时区 ID(例如 "GMT Standard Time")。根据 .NET 的实现方法和版本,您可能能够在任何平台上支持任何一种。 (如果您可以选择,我强烈建议您使用 IANA 时区 ID。)

在这种情况下,您应该只考虑一种极端情况。问问自己,您的餐厅是否有可能在一天中可能发生 fall-back 过渡的时间附近进行预订?

  • 当与 UTC 的本地偏移量减少时,例如 DST 结束时(例如伦敦的 BST 到 GMT),或者如果政府修改时区的标准偏移量,偶尔会发生这种情况.

  • 如果答案为“否”,则您无需执行任何其他操作。由于大多数餐厅不会在这些过渡发生的很晚的时间预订 table,我怀疑您可能就是这种情况。

  • 如果答案是“是”,那么您在预订时需要一些方法来消除歧义。例如,如果有人在 01:002021-10-31 预订了 table,您可能想问他们他们的意图是 01:00 BST(第一次出现)还是 01:00 GMT(第二次出现)- 因为那天是夏令时结束时时钟倒退的那一天。一个简单的布尔值可以存储这个意图。

如果您正在考虑使用 UTC-based DateTimeDateTimeOffset,我会请您考虑一下我关于 捕获意图的观点 .例如,您可能认为一家餐厅(在伦敦)在 DateTimeOffset 中记录 2021-10-30T18:00:00+01:00 的预订时间或在 [=10= 中记录其等效的 UTC 值 2021-10-30T17:00:00Z 没有任何问题].问题变成了 - 如果规则在活动预订时间和活动发生时间之间 发生变化 怎么办?也许政府提前一周结束夏令时,或者完全停止使用它。这种不规则的变化在世界各地的不同时区已经发生过多次,而且它们随时都有可能再次发生——在任何地方。一般来说,事件发生在未来的时间越多,我们就越不可能预测当时与 UTC 的偏移量。 (对于给出的示例,您应该捕获:2021-10-30T18:00:00"Europe/London"。)

如果您正在处理 重复发生的 事件,则此问题会加剧,因为偏移量可能 定期 仅更改为开始或停止夏令时。虽然我不确定餐厅是否会重复预订 table,但重复的会议、每日闹钟和其他周期性事件确实会发生这种情况。

最后我只想说总会有人说“总是使用 UTC”,但这种建议是短视的。总会有 UTC 不合适的用例,未来的调度肯定是其中之一。

好吧,这个业务案例似乎不需要它,但是当您仔细观察时,使用 UTC 格式的日期可能会在将来有所帮助,例如,如果您需要实现一项允许餐馆老板的功能将预订同步到不同的系统(日历...)。

对于“技术”日期字段(CreatedDateTime、UpdatedDateTime),您需要将它们存储在 UTC 时区,因为它们属于您的系统而不属于预订,因此您需要在不同时区保持一致你的客户。所以为了不让您的团队感到困惑,我会以 UTC 格式保存所有日期。