当前位置:  开发笔记 > 编程语言 > 正文

处理存储中的时区?

如何解决《处理存储中的时区?》经验,为你挑选了3个好方法。

将所有内容存储在GMT中?

使用嵌入式偏移量按照输入的方式存储所有内容?

每次渲染时都要数学吗?

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



1> Josh..:

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

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

Joel在其中一个播客中谈到了这个问题(以一种圆形的方式) - 他说要以尽可能高的分辨率存储你的数据(搜索"保真度"),因为你可以在它再次出局时随时进行播放.这就是为什么我说将它存储为UTC,因为当地时间你需要为那些不在那个时区的人调整,这是一项艰苦的工作.例如,当您存储时间时,您需要存储夏令时是否有效.育.

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

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



2> 小智..:

答案一如既往地是"依赖".

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

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

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

    历史数据

    未来的短期数据

    未来的长期数据

每个子类都有以​​下子类:

    系统提供

    用户提供

让我们一次看一个.

系统提供:我建议以UTC格式运行系统,然后避免时区问题,再次看不到信息丢失(它始终是UTC).

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

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

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

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

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

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

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

将它存储为名称.

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

如果开发人员继续以UTC格式存储所有内容,无论时区如何,我们将继续看到我们在最后一批时区变化中看到的问题.

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



3> Bwooce..:

Josh在上面完全正确,但我有一个微妙的警告要解释.这是一个没有关于未来事件和时区的正确答案的情况.

考虑重复约会的情况.它发生在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点会议自行移动时,演示很重要)

我必须相信我的同事和朋友Jason Pollock的这种见解.阅读他的观点,以及后续讨论iCal和VTIMEZONE.

推荐阅读
携手相约幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有