2008-08-15 51 views

回答

36

你必须以UTC存储 - 如果你不这样做,你的历史报告和行为在诸如夏令时之类的事情中会变得......有趣。 GMT是当地时间,受夏时制相对于UTC(不是)的影响。

如果您存储本地时间,向不同时区的用户演示可能是一个真正的混蛋。如果您的原始数据是UTC,则很容易调整到本地 - 只需添加用户的偏移量即可完成!

Joel在其中一个播客中谈到了这件事 - 他对store your data in the highest resolution possible(寻找'保真度')说,因为当它再次熄灭时你总是可以将它绊倒。这就是为什么我说把它作为UTC存储的原因,因为当地时间你需要为那些不在那个时区的人进行调整,这是很艰苦的工作。例如,当您储存时间时,您是否需要储存夏令时是否生效。育。

通常在过去的数据库中,我存储了两个UTC用于排序,本地显示时间。这样,用户和计算机都不会感到困惑。

现在,作为显示:当然,你可以做“3分钟前”的事情,但只有当你存储UTC时间时 - 否则,输入不同时区的数据将显示为“-4小时前“,这会让人大失所望。如果您要显示实际时间,人们喜欢在当地时间使用它 - 如果数据输入到多个时区,则只有在您存储UTC时才能轻松完成。

+0

但是,假设您有一个预订系统,并且您在3点钟用DST预订了一个时区的房间。当DST发生时,GMT与会议室时区之间的偏移量会改变一个小时。突然间,会议在不同的时间被预订了! – 2009-07-07 09:49:43

+0

没关系,我没有想到你会在会议发生的那一刻的DST偏移量中转换时间,所以它总是处于正确的偏移量。 – 2009-07-07 10:00:46

+0

不,GMT没有夏令时。如果我们是迂腐的,那么UTC不是一个时区。 GMT是基于格林威治的平均太阳时间。 UTC基于原子时间(TAI)调整了整数秒(闰秒),以保持接近地球的太阳能阶段,尽管它们可以相差达0.9秒。由于地球的旋转时间会发生明显的变化,您将不得不继续开会几年,但这就是为什么这里存在复杂性。 – mc0e 2017-02-20 11:43:59

1

个人而言,我看不到任何理由不将所有内容都存储在GMT中,然后使用用户本地时区显示与它们相关的时间。

如果你想显示相对时间,你显然仍然需要时间和做翻译,但如果你想做翻译,我认为GMT仍然是你最好的选择。

+0

问题是,自动化流程在向人们沟通时(比如说最后期限),什么时候使用?你是否按照他们的决定存储用户时区并在所有通信中使用它? – DevelopingChris 2009-07-09 14:54:07

0

我喜欢以GMT格式存储并且只显示相对(“大约10秒前”,“5个月前”)。用户不需要查看大多数用例的实际时间戳。

当然有例外,单个应用程序可能有很多这样的应用程序,所以它不可能是一个“一个真正的方法”的答案。需要强大审计能力(如投票)的事情,以及时间属于话语领域(天文学,科学研究)的系统可能需要向用户展示真正的时间戳。

虽然大多数应用程序只需简单的相对时间就可以更容易理解。

1

所以我跑了一点MSSQL服务器的实验。

我创建了一个表并添加了一个包含当前本地化时区(澳大利亚)的行。 然后我将我的日期时间更改为GMT并添加了另一行。

即使这些行相隔大约10秒,它们也会出现在SQL服务器中,因为它们相隔10小时。

如果没有别的,它至少告诉我,我应该以conisitent的方式存储日期,这对我来说,增加了将它们存储为GMT的参数的权重。

1

MS Dynamics存储GMT,然后在用户级别知道您的时区相对于GMT。然后它在您的时区显示给您。

我以为我会把它扔出去,因为这是MS的一个非常大的团体,这就是他们如何决定处理它。

0

我通常只使用Unix时间。不一定是未来安全的,但它工作得很好。

0

始终以GMT(或UTC)存储。从那里很容易转换到任何当地的时区值。

5

乔希以上是完全正确的,但我有一个细微的警告来解释。对于未来的事件和时区,这是一个没有正确答案的案例。

考虑重复约会的情况。它发生在格林威治标准时间0000(为了简单起见),即1200 NZST(新西兰标准时间)和1000澳大利亚悉尼EST。

当夏令时在一个区域生效时,约会应该发生什么?应该:

1a。如果TZ更改在 的区域内,约会的“所有者”( 预订了它),然后尝试在相同的服务时钟时间(例如上午10:00)保持在 ?
1b。如果 TZ的变化是在其他 会议参加者的区域之一,那么没有 变化

后果:它移动的 其他人一样,出乎意料的是,由于 业主TZ的变化,但它保持 “在上午10点会议“至于 所有者而言。 '

'2。如上所述,但相反。

后果:会议所有者(上午10点会议成为上午9点会议,或v/v),这可能是预期的但不方便。对于其他与会者来说,它们保持在同一时间段的时间,直到他们完成自己的TZ转换。

两者都不完美。考虑两个约会的情况,其中一个由A人在当地时间上午10点预订,另一个由B人以A人作为参加者在上午9点预订。如果A人和B人使用不同的TZ,那么DST变化很容易导致他们变成双倍预订。

如果你的思想有点弯曲在这一点上,那么我很明白。

这个例子背后的要点是,要正确地完成这些行为,不仅需要知道当地时间的UTC版本,而且需要知道拥有者在预订时的TZ(而不是偏移量) 。否则,你别无选择,只能采取选择2,默默无闻,甚至没有通知任何人事情发生了变化,因为格林尼治标准时间不会改变,只有演示文稿发生变化......对吗? (不,这是陷阱,当你的上午10点会议自己移动时,演示很重要)

我必须称赞我的同事和朋友Jason Pollock的这种见解。请阅读his view here,以及后续讨论iCal and VTIMEZONE

12

答案一如既往,是“依赖”。

这取决于您所描述的时间以及数据是如何提供给您的。 决定如何存储时间值的关键是决定您是否因丢失时区而丢失信息,以及您的用户不会感到意外。

将数据存储在UTC time_t中有确定的好处 - 它是一个int值,允许快速排序和轻松存储。

我认为问题被分解成具体领域:

  1. 历史数据
  2. 未来,短期数据
  3. 未来,长期数据

用下面的子类对:

  1. Sys TEM提供
  2. 用户提供的

让我们来看看他们一次一个。

系统提供:我会建议以UTC运行系统,然后避免时区问题,并且不会再出现信息丢失(通常是UTC)。

历史数据:这些都是一样的系统日志文件,进程统计,跟踪,评论日期/时间等数据是不会改变的,而时区描述符是不会去修改。对于这种类型的数据,不管其提供的时区是什么,通过以UTC存储信息都不会丢失任何信息。因此,请删除时区。

未来,长期数据:这些事件在未来或将持续发生。如果它们保持足够长的时间,则时区描述符可以保证更改。这类数据的一个很好的例子是“每周管理会议”。这是一次输入的数据,并且预计会永久运行。对于这些值,确定它是系统还是用户提供很重要。对于用户提供的数据,时间应该与创建者的时区一起存储,否则会导致信息丢失。当时区定义更改并且创建者显示的时间具有完全不同的值时,此信息丢失会变得明显!

正如Bwooce所指出的,创作者和观众在不同的时区中存在一些混淆。在那种情况下,我希望应用程序能够指出哪些时间值已经由于他们以前的位置的时区偏移而发生了移动。

未来短期数据:这是快速变为历史数据,或仅在短时间内有效的数据。例子可以是间隔计时器,评级转换等。对于这些数据,由于可能性很低,定义将在创建值和历史时间之间发生变化,因此可能会放弃删除时区。但是,我发现这些价值观有一个坏习惯,即成为“未来长期数据”。

一旦你决定存储时区,必须注意它的存储方式。

  • 不要将时区存储为偏移量或完整的描述符。

如果您将时区存储为偏移量,如果时区更改,您会怎么做?你是否会浏览系统并对现有数据进行全面更改?如果你这样做,你现在已经使任何历史值不正确。这个故障的好例子是Oracle和iCal。 Oracle将时区信息存储为UTC的偏移量,iCal包含创建时区的完整描述符。

  • 将它作为名称存储。

这允许更改时区的定义而无需修改您拥有的现有值。它确实使排序更加困难,因为如果时区数据更改,则生成的任何索引都可能无效。

如果开发人员继续以UTC格式存储所有内容,不考虑时区,我们将继续看到我们在最后一批时区更改中看到的问题。

在一个组织中,秘书必须在夏令时之前打印出团队的日历,然后在更改后再打印出来。最后,他们比较了两者并重新创建了所有已经迁移的约会。当然,他们错过了几次,直到旧的夏令时已经到来,并且时间再次变得正确时,还有几个星期的痛苦。

1

我更喜欢随时区存储所有内容。客户可以决定,它应该在稍后呈现的方式。 我最喜欢的图书馆是PostgreSQL-Database

2

以GMT/UTC存储所有内容对我来说似乎最合乎逻辑。然后,您可以在每个需要的时区显示日期和时间。

几个ceveats:

  1. 如果时间仅指定为 挂钟时间,那就是 领导表示,那么它是不是 绝对指定的时间。 您应该(也不能)在任何格林威治标准时将其转换为 。例如。每天早上9:00 AM。换句话说: 这是没有(日期)的时间。
  2. 如果 节省未来 预约的日期和时间,你应该使用 抵消由输入 时区指定GMT和的时刻 本身。因此,如果在例如冬季在夏季制作的约会 西欧,它是+2:00, 所有虽然正常(冬令时) 抵消是+1:00。这将解决Bwooce 提到的日历问题。
  3. 当然,这适用于使用权 偏移而转换成GMT 在任何特定 时区转换回 日期和时间应用相同的 。

幸运的是,如果使用正确,(.NET)DateTime类型会照顾所有保存日历等等的细节,当你知道它是如何工作的时候,所有这些都应该很容易。

1

看看这里,w3c做了很好的回答。

看看用例。

http://www.w3.org/TR/timezone/

注意,他们建议存储日期时间为UTC不GMT,格林尼治标准时间受到日光节约时间。