温馨提示: 本文使用 New Bing 润色 。
参考链接:
Day.js: Day.js · 中文文档 - 2kB 大小的 JavaScript 时间日期库 (gitee.io)
uniCloud: https://uniapp.dcloud.net.cn/uniCloud/
时区换算: https://www.timebie.com/cn/stduniversal.php
彻底弄懂 GMT、UTC、时区和夏令时: https://zhuanlan.zhihu.com/p/135951778
国际标准时间格式 ISO8601 - Yungyu - 博客园 ( cnblogs.com ): https://www.cnblogs.com/yungyu16/p/12532603.html
如何给容器配置时区 (Timezone): https://zhuanlan.zhihu.com/p/165085756
最近在使用 uniCloud 开发云函数时,需要用到 Day.js 这个 JavaScript 库,它可以方便地处理日期和时间的问题。但是由于 uniCloud 的云函数默认使用的时区是 UTC+0,而不是 UTC+8,所以必须对时区进行一些调整。
在这个过程中,遇到了一些困难和解决方法,特此记录。
什么是时区和 UTC
时区是指地球上不同地区的时间差异,通常以经度为依据,每隔 15 度划分一个时区。
UTC 是协调世界时,是一种基于原子钟的时间标准,用来统一全球各地的时间。
UTC 不与任何地区位置相关,也不代表此刻某地的时间,所以在说明某地时间时要加上时区。
比如北京位于东八区,领先 UTC 8 个小时,所以北京时间 = UTC + 8 小时。
为什么你需要关注时区
作为一个开发者,你可能经常使用 UTC + 8 时区,也就是北京时间。如果你的用户和服务器都在国内,那么时区问题对你来说可能不是什么大事。但如果你的用户或服务器在其他地区,那么时区问题就会变得很重要。
想象一下,如果你的服务器在美国东部(UTC - 5),而你的用户在中国(UTC + 8),那么当服务器发送一个时间数据给用户时,比如 2023-03-19T12:00:00+08,用户看到的就是北京时间的中午 12 点。但实际上,这个时间对应的是美国东部的凌晨 11 点。这样就会造成误解和混乱。
为了避免这种情况,服务器端一般存储的是 iso 格式的时间,自带时区信息,例如:2023-03-19T12:00:00+08、2023-03-19T04:18:59.008Z 等。这样,在传输到用户端之后,就可以根据本地时区进行转换显示。例如,上面的两个时间,在中国显示为北京时间的中午 12 点和下午 12 点 18 分 59 秒,在美国东部显示为凌晨 11 点和凌晨 4 点 18 分 59 秒。
所以,在处理时间时需要考虑时区问题,以保证数据的正确性和一致性。
Day.js 相较于其他类似的库的优势
关于这一点,实际上在 Day.js 的官网已经说的很明白了:
Moment.js 的 2kB 轻量化方案,拥有同样强大的 API。
下载、解析和执行更少的 JavaScript,为您的代码留出更多时间。Day.js 是一个轻量的处理时间和日期的 JavaScript 库,和 Moment.js 的 API 设计保持完全一样。
如果您曾经用过 Moment.js, 那么您已经知道如何使用 Day.js 。
所有的 API 操作都将返回一个新的 Dayjs 对象。
这种设计能避免 bug 产生,节约调试时间。
Day.js 对国际化支持良好。但除非手动加载,多国语言默认是不会被打包到工程里的
相较于 Moment.js 16.7 kB 的体积, Day.js 非常的轻量化,这也是我从 Moment.js 转为 Day.js 的原因。
Day.js 处理时区问题
遇到的问题
Day.js 默认是 不处理 时区问题的,所以需要引入 Timezone 插件 ,即:
const utc = require('dayjs/plugin/utc') const timezone = require('dayjs/plugin/timezone') // dependent on utc plugin dayjs.extend(utc) dayjs.extend(timezone) dayjs.tz.setDefault("Asia/Shanghai") // 设置时区为上海,东八区,UTC + 8
但这里有一个小问题,即
timezone
插件只影响dayjs.tz()
的行为,不影响dayjs()
的行为。(见:设置默认时区 · Day.js (gitee.io))所以引入
timezone
插件后要改为调用dayjs.tz()
才能获取到指定时区的dayjs
对象。const dayjs = require('dayjs') const utc = require('dayjs/plugin/utc') const timezone = require('dayjs/plugin/timezone') // dependent on utc plugin dayjs.extend(utc) dayjs.extend(timezone) dayjs.tz.setDefault("Asia/Shanghai") dayjs() // 依旧是服务器/本地时区 dayjs.tz() //这样才是指定的时区
处理时区问题的终极解决方案
如果我就是想直接调用
dayjs()
来获取指定时区该怎么办?那么也很简单,只要设置
TZ
这个环境变量即可。process.env.TZ = 'Asia/Shanghai'
TZ 环境变量是用来设置时区的一个变量:https://zhuanlan.zhihu.com/p/165085756