最近在一个项目中做时区转换时出了点问题,起因是前端需要根据用户设置的时区,显示不同时区的时间,拿到服务端返回的时间戳,在表格中显示是正常的,在编辑界面保存后总是差八个小时,出现这种情况的原因我分析如下:

关于时间戳,我们有一个共同的认知,“假设浏览器所在电脑的时间是准确的,那么世界上无论哪个时区的电脑,它们此刻产生的时间戳数字都是一样的,所以,时间戳可以精确地表示一个时刻,并且与时区无关”。这句话是没错的,任何一个时区的同一个时刻,产生的时间戳肯定是一样的,那不同时刻呢?时间戳肯定会不一样吧,比如下面的例子:

a = new Date() //东八区 10:43:27
// Sat Jul 01 2023 10:43:27 GMT+0800 (China Standard Time)
b = new Date(a+' GMT+0900') // 东九区此刻,显示为东八区时间是 09:43:27
// Sat Jul 01 2023 09:43:27 GMT+0800 (China Standard Time)
a.valueOf()
// 1688179407305
b.valueOf()
// 1688175807000

为什么要用上面的代码来做 demo 呢?因为 element-ui 的时间组件总是以本地时间显示的,没有时区这个概念,拿的时间戳自然也总是拿的本地时间戳。用户选了UTC时区,打开编辑界面,实际上element-ui时间组件显示的是本地时间,时区说明只是个障眼法,让用户以为他看到的是UTC时间,实际上这个本地时间跟 0 时区是偏移了几个时区的,换句话说我们看到的八点,在 0 区才凌晨,所以应该是保存的凌晨,而不是八点的时间戳。

基于以上分析,在编辑界面拿时间戳的时候,需要根据时区拿,保存的才会是正确的时间点,根据时区获取时间戳的方法如下:

// 本地时间转换为东八区时间
_time = _time + ' GMT+0800'
let realTime = new Date(_time).valueOf()
// 本地时间转换为UTC时间
_time = _time + ' UTC'
let realTime = new Date(_time).valueOf()

参考文献:
浅析 JS 处理时间时区问题、将时间戳或时间对象转成字符串格式