编程和世界时间

英文地址

时间编程的复杂度

所有需要在代码中处理多个时区的人都会考虑如何处理时区。但是很多人并没有完全理解时区的运作原理,这篇文章将详细介绍这个问题。

什么是时区

因为地球在以24小时左右一圈的速度进行公转,纬度不同的地方中午的时间不同(注:这里的中午是指太阳在当地上空正中间的那个时刻)。如果我们希望每个地方的中午统一为12:00,那么不同地区的时钟设置必然不同。如果我们希望中午的时间误差在1分钟内,那么我们需要设置1440个时区。
如果我们不进行远距离旅行或者沟通,那么上述方法完全没有问题。这也确实是19世纪时的情况。但是当铁路、即时通信技术出现后这种情况就被打破。
为了解决这个问题,人类创立了“时区”这个概念。但是我们只设置了24个时区而不是1440个。主时区GMT,各向东西方向延伸7.5度,那么我们总共有24个时区,每个时区延伸15度。但是不少国家和领地往往自行决定他们属于哪个时区,因此导致了下图这种情况:
Alt
尽管如此,目前看来时间计算也并没有那么复杂,因为我们只要根据不同地区设置不同时区即可。但其实还有其他因素需要考虑。

UTC vs GMT

GMT是英国格林威治太阳时间。它是英国冬令时时间,但是他们在夏令时使用BST(british summer time)。UTC并一个是时区而是国际时间标准。UTC尽量靠近GMT时间,而其他时区通过偏移量来表示。

夏令时(DST)

夏令时是指在夏天将时间后拨一个小时来节省能源(是否可以产生效果目前具有很大争议)。目前北美和西欧仍然使用DST,但是大部分亚洲国家、俄罗斯并未使用。
夏令时导致我们无法只通过地理位置判断时间,而必须考虑夏令时是否生效。在夏令时开始和结束的那两天问题会变得更加复杂:开始那天时间只有23小时,而结束那天时间达到25小时。
我们来下09:00 UTC时间时位于"america/denver”时区的本地时间变化情况。在将要进入09:00UTC时间时当地时间将变成02:00,但是夏令时生效后,当地时间直接变成了03:00.
Alt
当秋天到来时问题会更加复杂。在接近08:00 UTC时 当地时间接近2:00,然后当夏令时取消时,当地时间“回退”到1:00导致1:00和2:00之间的时间发生了两次!
Alt
更糟糕的事我们没有一个明确的规则知道夏令时什么时候开始和结束。一直到2007年,美国、西欧和加拿大都采用同样的夏令时变化方式。但是2007年美国国会为了怀俄明州的孩子有更长的白天享受万圣节而延长了夏令时时间。从此之后,每年西欧和北美都有3-4个星期的时间差值不同。更不要说欧盟统一在1:00 utc“回退”时间,而不是在不同时区的同一时间。

例外

现实情况比上述更糟糕,比如虽然美国实行夏令制,但仍有很多州未使用。而印度部分行省使用中央时间,其他地区使用东部时间。也不是所有地区的当时时间和UTC的差值都以小时为单位,有些地区的时间比utc快1.5小时或者2.5小时,甚至有45分钟的情况。

编程时使用时间

通常我们需要考虑如下因素:

本地时间容易导致混乱

尤其在使用夏令制的地区,如果我们只存储本地时间将因为上述“回退”导致时间混乱,也无法将这个时间转换为UTC或者其他时区的时间。

使用utc保存时间

通常来讲最好的方式是将本地时间转换为utc时间并存储,然后可以转换为任意时区的时间并展示。这种方法也可以同时处理夏令时的问题。
目前的编程语言基本都支持时间转换,所以在转换时我们不用担心上面这些问题。但是如果有人认为只要存储了本地时间和本地时间相对utc的偏移量就足够了,那么这绝对是错误的看法。

数据库

大多数数据库都支持DateTime数据类型,其中有些内置了时区转换,在使用这些数据库前需要详细了解他们如何处理时区。

web

web程序需要考虑的更多,但是有一点可以明确:我们可以使用js脚本获取当前用户所在时区并回传给服务器。但是有时候最好允许用户自行选择时区而不是使用当前时区,这和我们需要处理的数据也有关系:有些数据和某一特定时区紧密关联,而有些数据需要转换为用户的当地时区显示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值