我需要确认在预订桌位时间中是否真的需要使用UTC时间?

4
这可能是一个愚蠢的问题,我提前道歉,但考虑到业务背景,我真的需要在数据库中保存表格预订时间并担心在Web客户端上转换为本地时间吗?
预订将始终针对特定位置(地理/城市)进行,因此无论当前是什么时候偏移utc(夏令时或否等),下午3:00的预订时间对于该位置来说都是下午3:00,无论未来还是过去。 这不是在线发生的事件,而是餐厅的现场活动。
我觉得即使我们开始在另一个国家进行预订,例如西班牙,具有明显不同时区,这个规则也仍然适用。伦敦的下午3:00与西班牙的下午3:00不同(在utc中),对系统来说并不重要,对吗?
我有没有漏掉什么非常明显的东西? 我不能简单地忽略处理不同的时区,只需在没有偏移量的情况下保存时间(假设所有时间都是当地时间,当地时间为该位置)吗?

答案取决于需要遵守时区的夏令时设置。如果没有,那么就没有必要存储它。话虽如此,为了未来的考虑,最好始终存储UTC时间,以防管理机构决定更改夏令时政策。 - Julius
“Table booking” 是指餐厅预订应用程序吗?考虑一种情况,您将业务范围扩展到整个欧洲,从冰岛到东欧(四个时区)。现在,您想运行“每日报告” - 什么时候结束一天?如果您成功地扩展到北美或澳大利亚,情况会变得复杂。将所有内容存储在UTC并进行转换非常容易。事后进行改装非常困难(尽管可能不像这里那样困难,因为您是伦敦的,并且使用UTC或夏令时)。 - Flydog57
始终使用协调世界时(UTC)时间。如果用户连接的时区与您不同,则无需从每个客户端获取时区。DateTime在Net中以UTC数字形式存储。然后,在将DateTime转换为/自字符串时,根据文化(时区)进行自动转换。 - jdweng
感谢@jdweng,API公开了一个端点用于创建预订,该端点具有zoneid,并且我正在将窗口时区存储在数据库中,因此我始终知道原始时区。即使目前仅用于验证开始时间(必须在未来)。 - Kcats Wolfrevo
3个回答

6
鉴于你所说的:
“…但是考虑到业务背景,我是否真的需要在数据库中保存UTC的表预订时间并担心在Web客户端上进行本地时间转换呢?”
“…这不是一个在线事件,而是一家餐厅的线下活动。”
对于此用例,您不应使用UTC。您记录的不是某事发生的绝对时间点(现在或过去),而是捕获未来事件的何时何地的“意图”。
当输入预订日期和时间时,顾客提供了“何时”的部分,他们使用餐厅所在地的本地时区提供它。将其转换为UTC或其他时区可能会丢失该意图。
假设这是单个预订(而不是重复规则),则在.NET中,可以使用DateTime类型,并将其Kind属性设置为DateTimeKind.Unspecified(在许多情况下是默认值)。
提供“何地”的部分由您提供,当您设置系统或添加新的餐厅位置时。最好保留每个餐厅的时区标识符或在您的系统中记录,而不是隐式地进行。在.NET中,应使用与TimeZoneInfo对象的Id属性相对应的字符串值。这是IANA时区ID(例如“Europe/London”)或Windows时区ID(例如“GMT Standard Time”)之一。根据实现方法和.NET版本,您可以在任何平台上支持其中任何一个。强烈建议使用IANA时区ID。
在此场景中只有一种边缘情况需要考虑。自问,您的餐厅是否可能在回退转换可能发生的那天接近预订时间?
  • 当本地与UTC的偏移量减少时(例如伦敦从英国夏令时转为格林威治标准时间),或者政府修改某个时区的标准偏移量时,就会发生这种情况。

  • 如果回答是“不需要”,那么你就不需要再做其他事情了。由于在这些转换发生时,大多数餐厅都不会在非常晚的时间预订桌子,我怀疑这很可能是你的情况。

  • 如果回答是“是”,那么你需要一些方法来澄清预订的时间。例如,如果有人在2021-10-3101:00预订了一张桌子,你可以询问他们的意图是01:00 BST(第一次发生)还是01:00 GMT(第二次发生)——因为那是夏令时结束时钟回拨的那一天。一个简单的布尔值可以存储这个意图。

如果你正在考虑使用基于UTC的DateTimeDateTimeOffset,我会建议你考虑一下我的看法,即要捕捉意图。例如,你可能认为一个餐厅(在伦敦)记录2021-10-30T18:00:00+01:00的预订时间在DateTimeOffset中没有问题,或者在DateTime中使用其相应的UTC值2021-10-30T17:00:00Z。问题在于,如果规则在事件预订时与事件发生时之间改变了呢?也许政府提前一周结束夏令时,或者彻底停止使用它。这种不规则的更改已经多次发生在世界各地的各种时区,而且任何地方都有可能再次发生。通常情况下,事件发生的时间越靠未来,我们就越难以预测该时间偏离UTC的偏移量。(对于给定的示例,应捕捉:2021-10-30T18:00:00"Europe/London"。)

如果你正在处理重复事件,这个问题会更加严重,因为偏移量可能会定期地发生变化,只要开始或停止夏令时。尽管我不确定餐厅是否会预订重复的桌子,但这种情况确实会在重复的会议、每日闹钟和其他周期性事件中发生。

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


嗨,马特,非常感谢你详细的回答,我同意你关于“意图”这件事的看法(我部分怀疑这是我情况的原因)。你提到的所有边缘情况对应用程序来说都不相关,但很高兴你在这里详细说明了它们。是的,我正在保存时区与位置(尽管是Windows的!)。 - Kcats Wolfrevo

1
我会给出一个可能不太受欢迎的观点,如果你确定编写的应用程序只处理单个位置的预订,则无需担心时区。你可以将服务器和/或数据库的时区设置为该位置的时区,然后忘记它。
唯一的例外是如果该时区遵循夏令时。在这种情况下,我建议将预订时间存储为UTC,并在必要时转换为该位置的时区;否则,在DST切换发生时,您的预订可能会差一个小时。
总的来说,我认为将时间存储为UTC是最佳实践,因为您知道它们始终是正确的,但我确实理解进行时区转换是一件麻烦事,可能在某些应用程序中并不值得努力。

0

嗯,这个业务场景可能看起来不需要,但是当你仔细一看,将日期保存为UTC时间可能会在未来有所帮助,例如如果你需要实现一个功能,允许餐厅所有者将预订同步到另一个系统(日历...)。

对于“技术”日期字段(CreatedDateTime、UpdatedDateTime),你需要将它们存储在UTC时区,因为它们属于你的系统而不是预订,所以你需要在客户的不同时区之间保持一致性。因此,为了不让你的团队混淆,我建议将所有日期保存为UTC时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接