GMT 时间与 UTC 时间转换那些事

924 阅读3分钟

背景

笔者昨天处理客户的一个工单,导致问题的原因是新上的功能里有一处 GMT 时间和 UTC 时间转换的业务逻辑存在错误,导致最终效果与预期结果不符合。在处理完工单问题后,引发了笔者对GMT 时间与 UTC 时间转换的深度思考

工单问题

复现一下工单中描述的问题:有一处业务逻辑是将用户设置的时间(UTC 时间)减去一小时,得到的新状态用于别的业务场景。笔者查看这部分代码时,看到如下的代码

function getTime(date) {
  var currentDate = new Date(date);

  currentDate.setHours(currentDate.getHours() - 1);
  return currentDate;
}

这段代码明显是有问题的,因为经过 new Date() 处理过的时间是 GMT 时间,所以最后返回的 currentDate 时间是 GMT 时间,并且是 Object 类型,而期望结果是需要一个 UTC 时间,并且类型是字符串

我是如何解决工单问题的

因为这个工单问题优先级很高,所以必须赶快处理,所以笔者用最省力的方式解决该问题,如下

在项目中引入 dayjs 第三方库来处理

npm i dayjs --save

然后重新封装 getUTCTime 方法,

// getUTCTime.js

import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'

dayjs.extend(utc)

function getUTCTime(date) {
    return dayjs.utc(date).subtract(1, 'hour').utc().format()
}

getUTCTime 测试结果如下

getUTCTime('2024-04-03T08:04:51.184Z')

// '2024-04-03T07:04:51Z'  结果符合预期

工单问题就这样解决了

进一步思考

工单问题虽然解决了,但是引起笔者深度思考 GMT 时间与 UTC 时间转换问题,首先我们来看一下 GMT 和 UTC 时间的基本概念

GMT(格林威治标准时间)是世界上最常用的时间标准之一,它是由英国的格林威治天文台所确定的时间标准。GMT不考虑夏令时的调整,因此它在全年内保持不变。它通常作为世界其他时区的参考标准,用于协调跨时区的活动和事件。

UTC(协调世界时)是世界上广泛使用的时间标准之一,它是基于原子钟的时间测量所确定的。与GMT相比,UTC更加精确,并且不会受到地球自转速度变化的影响。UTC与格林威治标准时间(GMT)几乎相同,但是它是一个更加准确的时间标准,并且包含了对闰秒的调整。UTC通常被认为是世界上的基准时间,其他时区通过与UTC的偏差来确定自己的本地时间。

GMT 和 UTC 时间的官方定义条条框框,啰里八嗦,那么我们就这样简单理解,GMT 带时区,UTC 不带时区。比如中国在东八区,那么 UTC 时间加上 8 小时就是 GMT 时间

GMT 和 UTC 转换

在解决工单问题中,笔者引入第三方库去转换时间,虽然 dayjs 只有 2kb 大小,但是对于这么小的功能,能不能使用原生 JS 解决呢?

笔者翻阅资料,发现 Date 对象有一个 toISOString 方法,用于将 Date 对象转换为符合 ISO 8601 格式的字符串表示。ISO 8601 是一种日期和时间的国际标准格式,它的格式类似于:"YYYY-MM-DDTHH:mm:ss.sssZ",这应该是我们想要的方法

那么对 getTime 方法进行重构如下

function getTime(date) {
  const currentDate = new Date(date);
  currentDate.setHours(currentDate.getHours() - 1);
  return currentDate.toISOString();
}

getTime 测试结果如下

getTime("2024-04-03T08:04:51.184Z")

// 2024-04-03T07:04:51.184Z

对比而言,仅仅只加上了 toISOString 就解决了问题,完全可以避免引入 dayjs 第三方库

总结

解决工程问题才是提升能力最好的方式,虽然这是一个很小的问题,但是在解决问题的过程中串联起多个知识点,解决问题的同时又了解新知识