如果您存储的是当地时间,那么向不同时区的"/>

关于本地化:处理存储中的时区?

关于本地化:处理存储中的时区?

Handling timezones in storage?

将所有内容存储在GMT吗?

使用嵌入的偏移量存储所有输入内容吗?

每次渲染时都会进行数学运算吗?

显示" 1分钟前"的相对时间?


您必须存储在UTC中-否则,您在诸如夏令时之类的历史报告和行为会变得很有趣。 GMT是当地时间,相对于UTC不受夏令时限制。

如果您存储的是当地时间,那么向不同时区的用户介绍可能是一个真正的混蛋。如果原始数据使用UTC,则很容易调整为本地-只需添加用户的偏移量就可以了!

Joel在一个播客中谈到了这一点(以一种循环的方式)-他说要以尽可能高的分辨率(搜索"保真度")存储您的数据,因为您总是可以在它存储时对其进行修改再次出去。这就是为什么我说将其存储为UTC的原因,因为本地时间需要针对不在该时区的任何人进行调整,因此这是很多艰苦的工作。并且您需要存储例如在存储时间时夏时制是否生效。 k

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

现在,显示如下:当然,您可以做" 3分钟前"的事情,但前提是要存储UTC-否则,在不同时区输入的数据将做类似显示为" -4"的事情几小时前",这会吓到人们。如果要显示实际时间,人们会喜欢在当地时间显示它-如果要在多个时区中输入数据,则只有在存储UTC时才能轻松做到这一点。 >


答案始终是" depends "。

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

在UTC time_t中存储数据有明显的好处-它是单个int,可以快速排序并易于存储。

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

  • 历史数据
  • 未来短期数据
  • 未来长期数据
  • 每个具有以下子类:

  • 系统提供
  • 用户提供
  • 让我们一次看看它们。

    提供的系统:我建议使用UTC运行系统,这样可以避免时区问题,并且再也不会看到信息丢失(始终为UTC)。

    历史数据:这些是系统日志文件,进程统计信息,跟踪,注释日期/时间等内容。数据不会更改,并且时区描述符也不会追溯更改。对于这种类型的数据,无论将信息提供在哪个时区,都不会通过将信息存储在UTC中而丢失任何信息。因此,请删除时区。

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

    正如Bwooce所指出的那样,创作者和观看者位于不同时区存在一些困惑。在那种情况下,我希望该应用程序指示由于从其先前位置移出时区而移动了哪些时间值。

    未来的短期数据:这些数据将很快成为历史数据,或仅在短时间内有效。例如间隔计时器,等级转换等。对于此数据,由于定义在值的创建和变为历史的时间之间变化的可能性很小,因此可能有可能放弃时区。但是,我发现这些值有成为"未来的长期数据"的坏习惯。

    一旦决定存储时区,则必须注意其存储方式。

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

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

    • 务必将其存储为名称。

    这可以更改时区的定义,而不必修改现有的值。这确实使排序变得更加困难,因为如果时区数据发生更改,那么生成的任何索引都可能无效。

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

    在一个组织中,秘书必须在夏令时之前打印出其团队的日历,然后在更改后再次打印出来。最后,他们比较了两者,并重新创建了所有已移动的date。当然,他们错过了好几次,并且有数周的痛苦,直到达到了旧的夏令时,时间又恢复了。


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

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

    夏令时在一个区域中生效时,date应该发生什么?应该:

    1a。如果TZ变化在
    date的"所有者"(谁
    预订),然后尝试停留在
    相同的办公桌时钟时间(例如上午10:00)?
    1b。如果
    TZ变化是其中之一
    会议参与者的区域,然后否
    更改

    后果:它为
    其他所有人,由于
    所有者TZ改变了,但是仍然存在
    根据"上午10点会议"
    有关所有者。

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

    后果:它为会议所有者移动(上午10点的会议变为上午9点的会议,或v / v),这可能是预料之中的,但不方便。其他与会者将在相同的座钟时间,直到他们进行自己的TZ过渡。

    都不是完美的。考虑两个date的情况,一个date是由A人预定的,发生在当地时间上午10点,另一个date是由B人与A预定的,出席者是上午9点。如果人员A和人员B位于不同的TZ \\中,则DST更改很容易使它们成为重复预订的。

    如果此时您的想法有些弯曲,那么我很理解。

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

    我必须感谢我的同事和朋友Jason Pollock的这种见解。在这里阅读他的观点,并在此处讨论iCal和VTIMEZONE的后续操作。


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

    一些提示:

  • 如果仅将时间指定为
    挂钟时间,那是
    领导代表,那么它是
    不是绝对指定的时间。
    您应该(不能)将其转换
    以任何GMT表示形式。例如。 9:00
    每天早上。换一种说法:
    这不是(日期)时间。
  • 如果你
    保存未来的日期和时间
    date,您应该使用
    输入指定的GMT偏移量
    时区和时刻
    本身。所以如果要预约
    例如在冬季
    西欧,现在是2:00,
    尽管正常(冬季)
    偏移量是1:00。这将解决
    Bwooce的日历问题
    提到。
  • 当然一样
    适用于使用权利
    转换为GMT时的偏移量
    转换回
    任何特定的日期和时间
    时区。
  • 幸运的是,如果使用正确,(。NET)DateTime类型将为您处理保留日历等所有繁琐的细节,并且当您知道其工作方式时,所有这些都将非常容易。


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

    查看用例。

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

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


    我更喜欢将所有内容与时区一起存储。
    客户可以决定以后应采用哪种方式呈现。
    我最喜欢转换的库是PostgreSQL数据库。


    MS Dynamics存储GMT,然后在用户级别了解您相对于GMT的时区。然后它将在您的时区中向您显示项目。

    只是以为我会把它扔出去,因为这是MS的一个很大的团队,这就是他们决定处理它的方式。


    因此我对MSSQL服务器进行了一些实验。

    我创建了一个表,并添加了具有当前本地化时区(澳大利亚)的行。
    然后我将日期时间更改为格林尼治标准时间,并添加了另一行。

    即使这些行以大约10秒的间隔添加,它们在SQL服务器中的间隔时间也为10个小时。

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


    我个人看不出没有将所有内容都存储在GMT中,然后使用用户本地时区显示与他们相关的时间的原因。

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


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

    但是不要以为在所有情况下始终100%的时间都可以正常工作。不会。


    始终存储在GMT(或UTC)中。从那里很容易转换为任何本地时区值。


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


    我喜欢存储在GMT中并仅显示相对值("大约10秒前"," 5个月前")。在大多数情况下,用户无需查看实际时间戳。

    当然有例外,单个应用程序可能有很多例外,因此它不是"单向方式"的答案。需要强大审计能力(例如投票)的事物以及时间是讨论领域(天文学,科学研究)的一部分的系统可能需要向用户显示真实的时间戳。

    不过,大多数应用程序在相对较短的时间内就更易于理解。


    推荐阅读