前端日期处理时区问题

今天有一个访客预约日期时段的项目出现了bug,经排查得出是js处理日期时间出现了时区的问题,正好当一个总结和笔记记录一下最好的解决方法和原理

由于世界各国和地区所处经度不同,每15经度划分一个时区,总共24个时区,各地区对应的本地时间和时区相关。并且存在不同的时间标准,例如我国使用 UTC 东八区的时间,以北京时间为准,为东8区。实际中国覆盖有东5、6、7、8、9这些时区.

世界时区

常见的标准时间有两种
1、GMT 格林尼治标准时间GMT是指位于英国伦敦的皇家格林尼治天文台的标准时间,本初子午线被定义在通过那里的经线,由于地球每天的自转有细微的不规则,而且正在缓慢减速,不再被作为标准时间使用。现在的主要标准时间使用 UTC(协调世界时间)。
2、UTC 协调世界时间UTC 是最主要的世界时间标准,由原子钟提供,经过平均太阳时、地轴运动修正 GMT格林尼治标准时间,以「秒」为单位的国际原子时所综合精算而成的时间。一般情况认为UTC和GMT是相等的。

JS 对不同时间标准和日期格式的处理

new Date().toString()
'Tue Jun 24 2025 12:36:11 GMT+0800 (中国标准时间)' 已经加上了东8区

new Date( ).toGMTString()
// 'Tue Jun 24 2025 13:16:11 GMT 基于 0时区

new Date('Mon Apr 17 2022 14:05:26 GMT+0800 (中国标准时间)').toUTCString()
// 2022-04-17T06:05:26.000Z
以上三种方法都会显示一种格林尼治的时间

但是对于同一个日期不同的格式,浏览器解析出来的时间也可能存在差异
在没指定时区的情况下,2025-06-24(符合 ISO 8601)被当做 UTC 0时区处理,转换成东八区,所以加上了8小时,并补上时区指示符;
2025-6-24(符合 RFC2822)被当做本地时区处理,因此不做时区转换,只补上了时区指示符。看下图

new Date('2025-06-24')
// Tue Jun 24 2025 08:00:00 GMT+0800 (中国标准时间)

new Date('2025-6-24')
//Tue Jun 24 2025 00:00:00 GMT+0800 (中国标准时间)

由于浏览器之间的差异与不一致性,强烈不推荐使用Date构造函数来解析日期字符串 (或使用与其等价的Date.parse)。对 RFC 2822 格式的日期仅有约定俗成的支持。 对 ISO 8601 格式的支持中,仅有日期的串 (例如 "1970-01-01") 会被处理为 UTC 而不是本地时间,与其他格式的串的处理不同。

前端处理的方法

方法 是否受本地时间影响 是否支持统一时区
全部统一本地格式化日期
.tolISOString
dayjs+timezone

最好使用dayjs+timezone来进行处理,这样无论用户是在哪个地方都会得到固定的时区时间,比如他在东京还是美国都会得到北京标准时间

为什么这种方式不受本地时间影响呢?

因为timezone可以指定使用某个时区(比如 Asia/Shanghai),而不是依赖用户系统时间
它内部根据当前时间和时区规则自动计算偏移量;


全局封装一个获取当前东八区时间的方法

// utils/date.js
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'

dayjs.extend(utc)
dayjs.extend(timezone)

export function getChinaTime() {
  return dayjs().tz('Asia/BeiJing')
}

export function parseChinaTime(str) {
  return dayjs(str).tz('Asia/BeiJing')
}

dayjs + timezone 不受本地时间影响,是因为你可以主动指定一个固定的时区(如 Asia/BeiJing),从而绕过浏览器默认使用的本地时区
但是根据实际业务需求并解决不了根本

如果用户把电脑时间调快了一天,now 就会比实际时间快一天;
如果用户把时区改成美国,那 .toISOString()、.toString() 等方法的结果也会跟着变

JavaScript 中的 new Date() 是依赖用户的操作系统时间的,如果用户手动修改了系统时间,前端获取到的时间也会跟着变。

所以如果涉及到预约、支付等关键场景,最好还是从服务器获取时间,也就是调用接口由后端进行返回,之后所有时间判断都基于这个服务器时间。这样无论用户怎么改系统时间,都不影响业务。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容