我有一个简单的移动应用程序,可以在指定位置安排人们之间的未来事件。这些事件可以是物理的,也可以是虚拟的,因此为事件指定的时间可能与事件的"位置"位于同一时区,也可能不在同一时区。例如,可以在指定日期的当地时间上午 10 点为伦敦的两个人安排一次实体会议。或者,可以在指定日期的下午 4 点(一个人的时区)为不同时区的两个人安排 Skype 通话,尽管活动的"地点"只是"办公室",这意味着不同时区的两个不同地点。
我想知道以下设计是否适用于此应用程序:
-
在客户端上,它要求用户输入本地日期和时间,并指定事件的本地时区。
-
在服务器上,它将具有提供的时区的本地日期和时间转换为 UTC 时间戳,并仅存储此时间戳。
-
当客户端检索这些详细信息时,它仅接收 UTC 时间戳,并将其转换为与客户端当前时区相同的时区的本地时间。客户端的当前时区由当前系统时区设置决定,我认为该时区设置会根据客户端的位置自动调整(当然,假设客户端已连接到移动网络)。
我设计这个设计的主要动机是:
-
UTC 是绝对和通用的时间标准,您可以在任何时区之间相互转换。
-
用户只关心他们当前所在时区的本地日期和时间。
这是一个可行的设计吗?如果没有,哪些特定场景会破坏应用程序或严重影响用户体验?欢迎批评。
对于单个事件,知道它发生的 UTC 时刻通常就足够了,只要您拥有正确的 UTC 时刻(见下文)。
对于重复的事件,您需要知道它重复的时区...不仅仅是 UTC 偏移量,还有实际时区。例如,如果我在欧洲/伦敦安排每周下午 5 点与美国/Los_Angeles的同事会面,那么在一年中的大部分时间里,他们都会在上午 9 点举行......但是在一年中的几周内,它将在上午 8 点发生,而在一年中的几周内,它将在上午 10 点发生,这是由于观察 DST 的时间不同。
即使对于单个事件,您也可能需要考虑时区规则更改时会发生什么情况。假设我安排在 2018 年 3 月 20 日下午 4 点的会议,采用欧洲/伦敦时区。目前,这将发生在 UTC 偏移量为 0...但假设从现在到会议之间,时区规则会发生变化,将英国夏令时提前一小时。如果我在日记中把它写成下午4点,我可能不希望软件认为它实际上是下午5点,因为这是我们最初预测的UTC时刻。
我们不知道您的确切应用程序要求,但上述情况至少为可能存储本地时间和时区而不是 UTC 即时提供了论据......但是,您还需要弄清楚如果由于 DST 更改而最终跳过本地时间或模棱两可,该怎么办。(当时钟回落时,某些本地时间会出现两次。当时钟向前跳跃时,会跳过一些本地时间。如果规则在原始计划时间和实际事件之间发生更改,则明确的时间可能会变得无效或不明确。您可能应该在设计中考虑这一点。
为了简单起见,我的答案是:
- 如果要定义单个时刻,时区信息是多余的。一个UTC/Unix 时间戳完全定义了一个时刻。
-
您的设计似乎是可行的,但是在第2点上:我会在客户端转换为UTC/Unix时间戳,并且已经给出了这个时间戳以最终形式提供给服务器。原因:客户端已经拥有转换所需的信息(请参阅此计时)客户端-服务器-数据库建筑示例 - 它完全基于您描述的原则工作)。
-
一个可能的问题(如Jon Skeet在他的答案中描述的那样)是重复发生的事件,但这应该反映在建模方式中。时间。重复事件和固定事件之间的区别是后者完全定义了一个时刻(如UTC/Unix时间戳),而第一个只是一个可以应用的"函数"到当前时间,获取重复周期的下一个触发时间事件。但这可能与什么完全不同你问 - 无论如何,以某种方式区分重复出现模型中的事件(如果需要)和固定事件是一个很好的想法。
-
要做出的一个决定是:拉还是推?还是两者兼而有之?您是否希望服务器能够发送电子邮件,例如,当事件发生时通过?还是仅在客户端时才需要客户端警报应用程序正在运行?这些问题的答案将帮助您朝着适合您的设计。