`

关于时区、时间、时刻

阅读更多

关于时区,其实应该是个地理概念。通常情况下,当我们跟别人说:“现在是上午11点23分”这句话时,隐含了一个信息,那就是我们做了一个假设:我们都处在同一个时区——标准时间东八区,或者是电视上常说的“北京时间”。这也说明了一件我们平时可能并没太注意的一件事情,时间是和时区紧密挂钩的一个概念。

但时刻就不同了,他是一个和时区没有任何联系的概念,中国有句古话叫“此时此刻”,可以当做现在时刻的一个等价表达。换个更容易理解的方式说就是:此时此刻,可以表示是北京时间的上午11点23分,同时也是美国西雅图的晚上8点23分(按照西雅图的夏令时计算,两边时差相差15个小时)。

但是在这个缩写泛滥的时代,当你发现你需要和服务器上各种local time打交道的时候(尤其是server本身采用了不同时区的时间标准的时候),你会发现,这个时间其实并没有那么简单。CST/UTC/PST/PDT/DST这些恼人的缩写可能不仅仅搞的你晕头转向,更糟糕的是,可能会让某些你需要时间相关任务并没有按照你预期的时刻运行,而是跑到了另一个时刻了!

要想完全搞清楚上面那一串缩写,还是得回头看看时区的概念。注意,以下讨论仅仅针对时区划分模型,暂时忽略真实地理位置行政因素造成的时间在时区内的定义。(比如中国地理位置东西横跨几个地理时区,不过还是统一使用北京时间)

关于时区

理论上的定义,可以在wiki上查到,这里不再赘述。其实我们很容易理解将地球的经线做个24等分,每个等分段作为一个时区,因为人类规定了,一天24小时嘛。

但是问题也来了,每个时区时间由谁来定义?

一种简单粗暴的做法是:每个时区里面的人自己定义时间点来维护自己时区的时间(其实欧美很多地区的夏令时机制,说白了就是这么回事,人为将原本当地的时间调快了一小时)。但是,就像北京奥运会的口号一样,One World嘛,总得有个大家统一认可的标准来界定时间,至少是个指导时间。于是,全世界需要一个时间定义基准坐标点。本初子午线作为分隔东西经线的起点,作为这个基准点也就无可厚非了。于是GMT闪亮登场了。GMT是Greenwish Mean Time的缩写,也是普通人最熟悉的格林尼治标准时间的英文定义。正午十二点被定义为太阳在格林尼治上空最高点时的时刻。这样,这个东西经起点的时区的时间就定义好了,剩下的其他时区的只要简单依次递增或递减一个小时就出现了一套时间系统。

对应到计算机领域,绝大部分的数据库系统的系统时间,都采用GMT时间,这点是中国程序员需要格外注意的地方,这个可不是标准的北京时间哦。

按照上面的这个GMT时间为基准,中国的标准北京时间只要往前推8个小时就行了。恩,到目前为止,一切顺利,世界和平,挺好。世界上其他地区只要和类似于中国一样的方法,根据GMT时间往前或者往后推若干的小时就行了。但是上面的方法又有一个隐含的前提,就是GMT时间是准确不变的。悲剧的是,GMT时间是依赖英国皇家格林尼治天文台正午时间点的时间系统,这个依赖是个地球运转周期物理级别的依赖。由于地球围绕太阳运转的椭圆形轨道的不匀速运动以及地球本身自转的缓慢减速,于是,于是UTC出现了。(其实确切的说,UT1、UT2是为了修正GMT的最直接产物,那个是更地理上的概念,本文主要介绍计算机系统中经常遇到几个概念,所以忽略UT的概念。)

UTC的英文全称是Coordinated Universal Time,中文翻译为协调世界时,这个奇怪的缩写没有直接采用英文头母的顺序据说是因为英语和法语缩写形式彼此妥协的结果。UTC是以原子时秒长为基础,时刻上尽量接近格林尼治标准时间,可以在时间精度要求不高的情况下,甚至可以将UTC和GMT表示的时间等价对待。不过事实上他们确实不同。UTC中的C是协调的意思,这里主要是为了协调UT1,理论上,UTC和UT1在时刻上的误差不能超过0.9秒,这就要求,UTC实际上需要人为的在某一刻在现有UTC时间的基础上加减一秒(闰秒)来进行调节。至于神马时候来进行加减闰秒的处理,目前在巴黎有个专门的组织叫International Earth Rotation Service来干这个事情。

好了,清楚了UTC的概念之后,前面提到的几个其他没有介绍的缩写就好解释了。现在再来看CST(China Standard Time)、PST(Pacific Standard Time),中文字面翻译分别为中国标准时和太平洋标准时,分别对应的是UTC+8和UTC-8。分别是早于UTC8小时和晚于UTC8小时。对应的,还有很多XST(X为具体的地区的头母缩写),都是基于UTC时区的时间标准。

到目前为止,一切OK。但是欧美人士真是TMD的能折腾,处于对夏季日照时光充分利用,于是他们发明了DST(Daylight Saving Time)这个概念。基本思想就是在夏天白昼时间增长的情况下, 把当地时间人为调快一小时,这样晚上就会有更多的日照时间了。听起来好像有点自欺欺人的感觉,但据说有研究表明,美国人还真因为这个DST省了不少电。。。理解了DST之后,PDT(Pacific Daylight Time)就好理解了,就是在PST基础上调快一小时时间的结果。说白了就是人为的把PST从UTC-8的时区时间改成了UTC-7的时区时间,当然改完了就不叫PST,而是PDT,这个也是西雅图采用的夏令时(Summer Time)标准。

好了,到目前为止,之前列出来的几个缩写都大概介绍完了。但是有句至理名言我们还是不能忘记:“出来混,总是要还的!”

又出啥乱子了呢?

细心的人肯定会注意到,DST的实质是人为的从人们手里“借走”了1小时!就是说你丫的平白无故的就让哥少了一小时,这让是时间如生命的哥情何以堪啊。Ok,所以夏令时一过,你得欠债还钱啊,你得找一天把之前从哥手里拿走的那一个小时还回来。这个时间目前在美国被定为11月第一个周日的凌晨2点钟。就是说到了这个周日的2:00am时,当地时间会瞬间变成1:00am,然后继续往下走,懒人们忽然多了一个小时的睡眠时间。Sounds pretty good,right? 苦逼的程序员伤不起啊,注意了,如果你之前使用了诸如01:15 am PST这类的表达式来控制你的自动运行任务,在这种场景下,你会发现你的任务被自动触发了两次!这个可能完全不是按照你的预期的。这个危险时间段是1:00 am ~ 2:00 am。聪明的你肯定想到了,如果当初借时间的那一刻,刚好会发生相反的事情——你预先定义的一个任务没有运行!因为2:00 am被直接跳成了3:00 am。。。这个危险时间段是在美国实行DST地区的3月第二个周日凌晨的2:00 am ~ 3:00 am。

综合上面的两种case,如果你有一个需要daily自动运行的任务(这个任务必须每天执行,并且必须每天就一次运行),如果使用时区时间是受DST影响的(比如PST,CST就不用care这个问题),那你得格外小心1:00 am ~ 3:00 am这个时间段了。

集中任务调度系统设计的思考

基于上面对于时区、时间、时刻的介绍,我们会发现,对于大型组织的任务调度系统,如下几个基本点必须要考虑:

  1. 集中任务调度系统的必要性:这点我们可以看到,因为时间是基于具体的时区才有意义,而普通Server由于本身设置的不同,可能会采用不同的时区时间。这点就使一些通用的任务调度系统的任务安排如果基于linux本地cron很不稳定(注意:并不是所有的cron都支持时区设置)。于是,一个统一的集中式的任务调度系统就有了他存在必要性。
  2. 集中任务调度系统时间配置语义:这点非常重要。记住:时间是基于时区的!如果你的系统能够确定仅仅只在一个特定是时区context中使用,那就明确好这个约定。如果你是一个庞大的跨国组织公用的系统组件,这个组件必须支持不同时区配置,以方便用户使用。同时,这个也才能真正明确在一个物理的时刻调度一个什么样的任务。这个在系统设计上也应该尽量规避规则本身可能照成的二义性问题,比如上面提到的在受DST影响的地区可能出现的危险时间段:1:00 am ~ 3:00 am。
  3. 任务调度的重叠性考虑:通常这个因素会跟业务运行任务的执行时间紧密相关,如果一个任务的执行时间巨长,直到下一次任务开始运行时他还是没有运行结束,这时必须提供相应的定制选项,由用户来确定如果处理:强行停止上次任务?忽略本次任务?及时给出报警通知?或者。。。

编程语言对时区、时间的支持

有了上面时区、时间的了解,就可以更好的理解编程语言中对这些概念的支持。基本上各大编程语言都在本身或者扩展模块的基础上实现了上述概念。

以Java为例,很多人熟悉的java.util.Date类的一个默认实例,实际上就是以1970年1月1日00:00:00 GMT为基准,到当前时间点(这里说当前时刻应该更合理)的毫秒数。这里可以看出,其实Date实例本身并没有时区的概念,说是一个时刻的概念更合理。

但是需要你需要显示这个时间是,DateFormat接口就需要TimeZone的setter了。原因很简单,时间脱离了时区,就没有意义了。当然你可以不用设置,那么语言本身会默认帮你选择一个默认的系统时区来表示时间(通常这不是一个好的实践)。同样的,Calendar接口中也有相应的时区设置的预留设计。

 

分享到:
评论

相关推荐

    dates:使用时刻和时区的日期和时间助手

    @ cleverbeagle /日期使用时刻和时刻的时区的日期和时间助手。

    高考地理复习必须清楚的十大概念.docx

    1、时间、时刻、时段、时区、区时和地方时:时间即时段又叫时间间隔,指时间的久暂,通常是用开始和终了的时刻来表示;时刻是指时间的迟早即时段图像中的某一点,时刻因适用经度的不同分地方时和标准时(区时);地方时...

    timezonecomplete:带有时区,持续时间和间隔的广泛日期时间功能

    TimezoneComplete是一个日期/时间实用程序库,所有这些实用程序都知道时区和夏时制。 它提供了使用持续时间(UTC毫秒数)和周期(某些时区的规则间隔,在UTC中可能是不规则的)进行计算的功能。 它知道DateTimes(带...

    java入门教程

    你可以在日期和时间数据中包含时区,还提供对小数秒的支持。本课的重点在于怎样使用包含在 Oracle9i/10g 中新的日期时间数据类型的新日期时间函数。为了理解这些函数的工作方式,必须熟悉时区和格林尼治标准时间 ...

    java介绍课件

    java基础至此你可以在日期和时间数据中包含时区,还提供对小数秒的支持。本课的重点在于怎样使用包含在 Oracle9i/10g 中新的日期时间数据类型的新日期时间函数。为了理解这些函数的工作方式,必须熟悉时区和格林尼治...

    IOS 开发APP之关于时间处理详细介绍

    即任意一个时刻,这个地球上只有一个绝对时间值存在,只不过因为时区或者文化的差异,处于同一时空的我们对同一时间的表述或者理解不同。这个看似简单明了的道理,是我们理解各种与时间相关的复杂概念的基石。就像...

    Global-Meeting-Planner:跨时区的会议计划器

    全球会议策划人当人们分散在多个时区时,Global Meeting Planner是... #Meteor依赖关系: 自动发布不安全的铁:路由器流星平台momentjs:时刻tsega:bootstrap3-datetimepicker twbs:bootstrap #外部库: JS时区检测

    matlab学习系列29 灰色预测.docx

    通过模型预测异常值出现的时刻,预测异常值什么时候出现在特定时区内。 (3) 波形预测,或称为拓扑预测,它是通过灰色模型预测事物未来变动的轨迹。 (4) 系统预测,对系统行为特征指标建立一族相互关联的灰色预测理论...

    新国网标准程序

    a) 定时冻结:按照约定的时刻及时间间隔冻结电能量数据;每个冻结量可保存 12 次。 b) 瞬时冻结:在非正常情况下,可冻结当前的日历、时间、所有电能量和重要测量量的数据;瞬时冻结量 保存最后 3 次的数据。 c) ...

    Prayer Status Updater-crx插件

    使用提供的时区信息和位置协调,它使用祷告时间库设置安装/启动时的五个Salah时间,并创建内部应用程序警报,这些警报在Salah时间触发,以唤醒应用程序并更改您的Slack状态和打sn,Dnd设置在设置状态后立即创建另一...

    南极星万年历(NJStar Calendar) v2.30

    另外, 世界时钟可以让您时刻知道全球各处的时间, 各主要城市的日落日出时间, 经纬度, 夏时制起始和结束的时间, 国际长途区号以及两城市的飞行距离和24小时的时差对照. 用户可以在世界地图上移动鼠标, 找出想了解的...

    datetime-attribute:获取HTML的有效HTML datetime属性元素

    日期时间属性获取HTML <time>元素的 : 在特定时刻; 持续时间; 用于时区偏移量。 整个程序包 ,可以摇树。安装npm install datetime-attribute 在脚本中导入所需的功能: import { datetime , datetimeDuration , ...

    太阳方位角数据:用于生成包含太阳方位角数据的 ASCII 文件(报告)的脚本。-matlab开发

    它提示观察者的大地坐标、观察者的时区和开始时间[根据当地标准时间]。 然后,它询问必须生成太阳方位角数据的时间段和间隔。 它会创建一个包含太阳方位角数据的 MS Word 文件。 作者对 Vincent Roy 的脚本“sun_...

    poti-kaini-EN:POTI-board-Kai Ni英文版,适用于PHP7的OekakiBBS(PHP5.5〜,7.x,8.0)

    更改日志(时区:亚洲/东京,世界标准时间+09:00) [2021/02/10] v2.23.7 lot.210210.0 修复了未定义管理员密码(按撒但地语)时显示的错误消息 主题的template_ini.php中还有一条附加消息; 保留MSG040。 修复了...

    Java虚拟机运行时数据区

     java虚拟机多线程是使用线程轮流切换并分配处理执行时间的方式来实现的,在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令。为了线程切换后能够恢复到正确的执行位置,每条线程都需要一套独立的线程...

    嵌入式课程设计 华东交通大学

    功能:多功能时钟软件,根据使用者的需要,随时选择显示世界上各个时区的当前时间。 要求: (1) 对每个城市(例如:北京、东京、巴黎、纽约、德黑兰等)建立一个任务,显示当地时刻,时差准确,但是当前时刻不要求...

    date-io:通用javascript日期管理库的抽象

    它允许您构建任何UI日期或时间组件,同时利用用户项目中使用的相同日期管理库。 它简化了时区管理,允许您的代码返回与用户期望的类型完全相同的类型,并可以与特定的日历系统(例如)一起使用 专案 图书馆 资料...

    barktracker:使用英特尔 Edison 跟踪我的狗的吠叫,将吠叫记录到 data.sparkfun

    #Bark Tracker 此草图使用... Edison 会分析它听到的任何声音,然后在声音超过某个阈值时将声级和时间记录到 Phant.io 数据馈送中。 查看以了解如何构建电路。 链接 科技 节点.js MRAA 永远 要求 片刻 时刻.时区 硬件

    java笔试题算法-csa-challenge:比较连接扫描算法的各种实现

    时刻表由一组元组(出发站、到达站、出发时间戳、到达时间戳)表示。 站由索引标识。 时间戳是 unix 时间戳。 不要担心时区、有效期等。我们之前处理过数据。 它不是内存效率最高的实现,但它是最简单的(有些人认为...

Global site tag (gtag.js) - Google Analytics