数说程序中的时区问题
时区
由于各个国家和地区所处的经度不同,地球各个角落的人们迎接太阳的时刻也存在差异,我们经常开玩笑说美国人在努力工作的时候而我们在睡觉说的就是这 个时差问题。过去,人们通过观察本地太阳的位置测定时刻,称之为地方时,地球表面经度每隔 15 度,地方时刻相差 1 小时,因此不同经度地区地方时也就不同。
为了方便不同地方的人将本地时间转换成其他地区的时间,1884 年华盛顿子午线国际会议正式通过了时区的概念,按照经线从东到西将地球划分成 24 个时区,并将通过英国伦敦格林尼治天文台原址的那条经线称为本初子午线,设立为中时区,也就是零时区。
GMT 与 UTC
GMT,格林威治标准时间。指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,但由于地球自转的不规则以及速率减缓,实际上已经不能再作为标准时间。
UTC,协调世界时。经过平均太阳时、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,误差值在 0.9 秒以内,因此比 GMT 更加精确。不过一般情况下我们视 GMT=UTC。
UTC 偏移量
我们的地球自西向东旋转,东边的时刻要早于西边,因此每向东跨过一个时区应当将时钟调快一个小时,向西跨过一个时区则应将时钟调慢一小时。我国北京处于东八区,因此 UTC 偏移量表示为 UTC+8:00
或者 UTC+0800
。
时间戳
在程序中,与时间有关的数据我们通常以时间戳进行标记。时间戳是指格林威治时间 1970 年 01 月 01 日 00 时 00 分 00 秒(北京时间 1970 年 01 月 01 日 08 时 00 分 00 秒) 起至现在的总秒数。但是由于时区的存在,同一时间戳在不同地方代表的时间也不同,比如北京时间是上午八点,在英国刚刚好是零 点。
尽管我国幅员辽阔,横跨五个时区,但是为了方便行政管理,统一采用东八区作为标准时区,即北京时间,因此若程序只涉及国内范围那么基本不存在时区偏移问题,但是一旦涉及全球各区域的业务那么时区问题显然无法忽视。
new Date()
JavaScript 中我们通过 Date
对象获取及处理时间,但是需要注意, Date
对象获取的时间是根据系统设置的时区得来的,以下是我分别将电脑设置为北京时间和美国西雅图时间所获取到的时间:
可以看到两个时区相差 15 个小时,那么问题就产生了,如果我在中国想要查询西雅图 5 月 20 日的订单信息,那么以北京时区获取的时间戳进行查询对应的 西雅图时间则很可能是 5 月 19 日,因为北京时间的 15:00 才对应西雅图当地时间的 0:00。若时间细粒度再小一点那么问题会更明显,因此在处理此类问题 的时候需要考虑时区偏移,对时间进行时区的转化。
Moment Timezone
Moment Timezone
是一个 JavaScript 时区处理类库,可以帮助我们针对时间进行时区转换,该库以 moment.js
为基础,API 基本沿用于此。
// 将时间加上时区信息
moment.tz("2019-06-07 12:00", "America/Los_Angeles").format()
// 将当前时间转化成指定时区的时间
moment().tz("America/Los_Angeles").format()
// 将特定时间转化成指定时区的时间
moment("2019-06-07 12:00").tz("America/Los_Angeles").format()
以系统时间为北京为例:
有了这个库我们就可以随心所欲地转换时区了。
Moment.js
格式化日期
moment().format()
具体用法参见 Format 。
Unix 偏移量 (毫秒)
获取时间戳。
moment().valueOf()
开始时间、结束时间
moment().startOf('day') // week、month、year
moment().endOf('day')
用于获取一天开始结束的时间戳非常方便。
加减法
moment().add(7, 'days')
moment().subtract(7, 'days')
转换成 Date 对象
moment().toDate()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: CSS 层叠顺序知多少?
下一篇: 彻底找到 Tomcat 启动速度慢的元凶
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论