提问者:小点点

将时间存储在UTC总是一个好主意吗?还是这种情况下存储在本地时间更好?


通常,最好的做法是将时间存储在UTC中,并且如这里和这里所提到的那样。

假设有一个再次发生的事件,比如结束时间,它总是在同一本地时间,比如17:00,不管该时区夏令时是否开启或关闭。 并且还需要在特定时区打开或关闭DST时不手动更改时间。 这也是一个要求,每当任何其他系统通过API(即GetEndTimeByEvent)询问结束时间时,它总是以UTC格式发送结束时间。

方法1:如果决定存储在UTC中,可以将其存储在数据库表中,如下所示。

Event      UTCEndTime
=====================
ABC         07:00:00
MNO         06:00:00
PQR         04:00:00

对于第一个事件ABC,UTC中的结束时间为07:00 am,如果在2012年7月1日将UTC转换为本地时间,则将得到17:00本地时间;如果在2012年10月10日(时区DST开启的日期)转换,则将得到6:00 pm,这不是正确的结束时间。

我认为一种可能的方法是将DST时间存储在附加列中,并在时区打开DST时使用该时间。

方法2:但是,如果它存储为如下所示的本地时间(例如,对于事件ABC),它将始终是17:00在任何日期,因为没有从UTC到本地时间的转换。

Event      LocalEndTime
=======================
ABC         17:00:00
MNO         16:00:00
PQR         14:00:00

应用层将本地时间转换为UTC时间,通过(API GetEndTimeByEvent)发送到其他系统。

在这种情况下,将时间存储在UTC中是否仍然是一个好主意? 如果是,那么如何得到一个恒定的本地时间?

相关问题:是否曾经有一个好的理由来存储时间而不是UTC?


共3个答案

匿名用户

我认为,为了回答那个问题,我们应该思考使用UTC存储时间戳的好处。

我个人认为这样做的主要好处是时间总是(大部分)保证一致。 换句话说,无论何时更改时区或应用DST,您都无法及时往返。 这在文件系统,日志等方面尤其有用。 但在你的申请中有必要吗?

想两件事。 首先,关于DST时钟移位的时间。 您的活动是否可能发生在凌晨2点到3点之间(在时钟转换完成的那一天)? 那会发生什么呢?

其次,应用程序是否会受到实际时区更改的影响? 换句话说,你准备用它从伦敦飞到华沙,并适当地改变你的电脑时区吗? 在那种情况下应该发生什么?

如果你对这两个问题都回答“不”,那么你最好用当地时间。 它将使您的应用程序更简单。 但如果你至少回答了一次是,那么我想你应该给它更多的思考。

这都是关于数据库的。 另一件事是应用程序内部使用的时间格式,这应该取决于实际使用该时间所做的事情。

您提到过它通过API公开时间。 应用程序会在每个请求时查询数据库吗? 如果您在内部将时间存储为UTC,则需要这样做,或者确保在DST/Timezone更改时,缓存的时间将被调整/修剪。

它对时间本身有什么作用吗? 比如打印事件将在8小时后发生,或者大约在这段时间内暂停它自己? 如果是的话,那么UTC可能会更好。 当然,您需要考虑前面提到的所有问题。

匿名用户

我喜欢这样想:

计算机并不关心时间作为人类可以理解的表示。 他们不关心时区,日期和时间字符串的格式或其他任何东西。 只有人类才关心如何解释和表示时间。

让数据库做它擅长的事情:将时间存储为数字--可以是UNIX epoch(自1970-01-01以来经过的秒数),也可以是UTC时间戳(没有时区或夏令时信息)。 只有在必要的时候,你才会关心用一种人类可以理解的方式来表示时间。 这意味着在应用程序逻辑,报告系统,控制台应用程序或任何其他地方,人类都将查看数据。

匿名用户

以下内容并不适用于真正的多租户全球SaaS产品,因此本文针对的是简单的“业务线”应用程序开发人员。

存储为UTC是很好的,但是如果这样做,有一个要求会让你很痛苦:“你能给我写一个报告,告诉我每天发生多少个X吗?”

如果您将日期存储为UTC,则此要求将导致痛苦; 您需要在应用程序服务器上和报告中编写时区调整代码; 对包含日期条件的数据执行的每个特殊查询都需要将此因素考虑在内。

如果您的应用程序符合以下条件:

  1. 每个实例都基于单个时区。
  2. 时区转换通常是在办公时间以外进行的,或者您实际上并不关心事情的“持续时间”,以至于少了一个小时左右就会很重要。

我建议您将datetime存储为本地日期时间,同时使用一个库来隔离服务器时区配置问题(例如。NET世界中的noda.time)。