处理存储中的时区?

时间:2008-08-15 04:55:00

标签: localization internationalization timezone globalization

将所有内容存储在GMT中?

以嵌入式胶印输入的方式存储所有内容?

每次渲染时都做数学运算吗?

显示相对时间“1分钟前”?

13 个答案:

答案 0 :(得分:36)

你必须以UTC格式存储 - 如果你不这样做,你在夏令时等事件中的历史性报道和行为会很有趣。 GMT是当地时间,受夏令时相对于UTC(不是)。

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

Joel在其中一个播客中谈到了这个问题(以圆周方式) - 他对store your data in the highest resolution possible说(寻找'保真'),因为当它再次出局时你总能把它弄得一团糟。这就是为什么我说将它存储为UTC,因为当地时间你需要为那些不在那个时区的人调整,这是一项艰苦的工作。例如,当您存储时间时,您需要存储夏令时是否有效。育。

过去在数据库中我经常存储两个 - UTC用于排序,本地时间用于显示。这样,用户和计算机都不会混淆。

现在,至于显示:当然,你可以做“3分钟前”的事情,但只有你存储UTC时 - 否则,在不同时区输入的数据将会显示为“-4小时前” ,这将吓坏人们。如果你要显示实际时间,人们喜欢在当地时间拥有它 - 如果数据是在多个时区输入的,那么只有在存储UTC时才能轻松完成。

答案 1 :(得分:13)

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

这取决于您所描述的时间以及如何向您提供数据。 决定如何存储时间值的关键是决定是否通过删除时区丢失信息,同时也不会让用户感到惊讶。

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

我认为问题分解为特定区域:

  1. 历史数据
  2. 未来,短期数据
  3. 未来,长期数据
  4. 每个子类都有以​​下子类:

    1. 系统提供
    2. 用户提供
    3. 让我们一次看一个。

      提供系统:我建议您使用UTC运行系统,然后避免出现时区问题,再次看不到信息丢失(它始终是UTC)。

      历史数据:这些是系统日志文件,进程统计信息,跟踪,注释日期/时间等等。数据不会改变,时区描述符不会发生追溯改变。对于这种类型的数据,通过以UTC格式存储信息不会丢失任何信息,无论其提供的时区如何。因此,请删除时区。

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

      正如Bwooce指出的那样,创作者和观众在不同的时区有一些混淆。在这种情况下,我希望应用程序指出由于时区从以前的位置移位而移动了哪些时间值。

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

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

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

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

      • 将其存储为名称。

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

      如果开发人员继续以UTC格式存储所有内容,无论时区如何,我们都会继续看到我们在最后一批时区更改时遇到的问题。

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

答案 2 :(得分:5)

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

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

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

1a上。如果TZ变化在区域内     约会的“所有者”(谁     预订了)然后尝试留在     相同的台钟时间(例如上午10:00)?
 1B。如果     TZ改变是另一个     会议参加者的区域然后没有     改变

后果:它会移动     其他人,出乎意料的是,由于     业主TZ改变了,但它仍然存在     “上午10点会议”就此而言     老板很关心。

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

后果:它会移动给会议所有者(上午10点会议成为上午9点会议,或v / v),这可能是预期但不方便。它与其他与会者保持相同的台钟时间,直到他们完成自己的TZ过渡。

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

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

这个例子背后的要点是,要正确地执行这些行为中的任何一个,您不仅需要知道当地时间的UTC版本,还要知道所有者在预订时所处的TZ(而不是偏移量)。否则你别无选择,只能默默地选择选项2,甚至没有通知任何人事情发生变化,因为GMT时间不改变,只有演示文稿改变了......对吗? (不,这是陷阱,当您的上午10点会议自行移动时,演示很重要)

我必须相信我的同事和朋友杰森波洛克的见解。阅读his view here,以及后续讨论iCal and VTIMEZONE

答案 3 :(得分:2)

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

一些小事:

  1. 如果时间仅指定为a 挂钟时间就是这样 领先的代表,那就是 不是绝对指定的时间。 你应该(而且不能)转换它 在任何GMT表示中。例如。 9:00 每天早上好。换一种说法: 这不是(约会)时间。
  2. 如果你     保存未来的日期和时间     预约,你应该使用     偏移到输入指定的GMT     时区和时刻     本身。所以,如果是预约     在夏天在冬天做的例如     西欧,它是+2:00,     一切正常(冬天)     偏移是+1:00。这样就解决了     Bwooce的日历问题     提及。
  3. 当然,一样 这适用于使用权利 转换为GMT时的偏移量 转换回来时适用 任何特定日期和时间 时区。
  4. 幸运的是,正确使用时,(.NET)DateTime类型会为你保留日历等所有的血腥细节,当你知道它是如何工作的时候,这一切都应该很容易。

答案 4 :(得分:1)

我更喜欢用时区存储所有内容。 客户可以决定以后应该以哪种方式呈现。 我最喜欢的转换库是PostgreSQL-Database

答案 5 :(得分:1)

看看这里,w3c在回答这个问题方面做得非常出色。

查看用例。

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

请注意,他们建议将日期时间存储为UTC而不是GMT,GMT受夏令时限制。

答案 6 :(得分:1)

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

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

答案 7 :(得分:1)

所以我用MSSQL服务器进行了一些实验。

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

即使这些行间隔10秒左右被添加,它们也会出现在SQL服务器中,因为它们相隔10个小时。

如果没有别的,它至少告诉我,我应该以一种方式存储日期,这对我来说,增加了将它们存储为GMT的论点的重要性。

答案 8 :(得分:1)

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

以为我会把它扔出去,因为那是MS的一个非常大的小组,这就是他们决定处理它的方式。

答案 9 :(得分:0)

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

答案 10 :(得分:0)

我喜欢在GMT中存储并仅显示亲戚(“约10秒前”,“5个月前”)。用户不需要查看大多数用例的实际时间戳。

当然有例外,个别应用程序可能有很多例外,因此它不能成为“一个真实的”答案。需要强大审计能力的事情(例如投票)以及时间属于话语领域(天文学,科学研究)的系统可能要求向用户显示真实的时间戳。

但是,大多数应用程序通过简单的相对时间更容易理解。

答案 11 :(得分:0)

日期应存储为UTC,除非它是用户提供的数据,并且您不知道用户希望数据位于哪个时区。有时(非常罕见),您只需要存储小时,分钟,秒,天,没有任何时区的月份和年份组成部分,因此您可以将其吐回给用户。现在,对于新开发人员或不确定的用户,请存储UTC,您将达到99%正确率。

但是不要以为在所有情况下始终100%的时间都可以使用它。不会。

答案 12 :(得分:0)

我通常只使用Unix时间。未来不一定安全,但效果很好。