Ant Design dateTimeRange 组件 UTC 时间的时区问题

更新日期: 2022-08-11 阅读次数: 4255 字数: 468 分类: ReactJS

后台用 InfluxDB 存储的时序数据,查询时需要使用 UTC 时间。 为了偷懒,我的后台 go 接口没有对时间字段做处理,想直接使用前端传过来的 UTC 时间格式。

于是出现了一个低级的前端 Bug。

功能异常的请求

请求链接格式:

http://www.sunzhongwei.com/someAPI?current=1&pageSize=20&startTime=2022-08-09T01%3A10%3A16Z&endTime=2022-08-10T01%3A10%3A16Z

  • startTime: 2022-08-09T01:10:16Z
  • endTime: 2022-08-10T01:10:16Z

而界面上 dateTimeRange 组件显示的时间是

  • 2022-08-09 17:10:16
  • 2022-08-10 17:10:16

为什么差了 16 个小时。正常应该是 8 个小时才对啊。

发现问题了,只有打开页面时默认值是错的; 如果点击选择时间区间,就是对的差8个时区。 猜测是默认值使用 utc 时间,但是提交数据查询请求时,这个时间被再次转换,于是出现了两个八小时的时差。

时间加 TZ 的含义

The T is just a literal to separate the date from the time, and the Z means "zero hour offset" also known as "Zulu time" (UTC). If your strings always have a "Z" you can use:

不加 Z 代表是当前 locale 对应的时区。

参考: https://www.sunzhongwei.com/js-converts-datetime-string-contains-tz-utc-time

> let d = new Date(Date.parse("2019-01-01T00:00:00"));
Tue Jan 01 2019 00:00:00 GMT+0800 (中国标准时间)

> d.toISOString()
"2018-12-31T16:00:00.000Z"

修复方法

// 初始化设置默认值时,这里不使用 utc 时间,为了防止 transform 里再次被转换
// const startTime = moment().subtract(1,'d').utc().format();
// const endTime = moment().utc().format();
const startTime = moment().subtract(1,'d').format("YYYY-MM-DD HH:mm:ss");
const endTime = moment().format("YYYY-MM-DD HH:mm:ss");

// table field
{
  title: "时间区间",
  dataIndex: 'Time',
  valueType: 'dateTimeRange',
  colSize: 1.5,
  initialValue: [startTime, endTime],
  search: {
	transform: (value) => ({
	  // 转化值的 key, 一般用于事件区间的转化
	  // 如果不转换,就会变成 Time=1&Time=2
	  startTime: moment(value[0], "YYYY-MM-DD HH:mm:ss").utc().format(),
	  endTime: moment(value[1], "YYYY-MM-DD HH:mm:ss").utc().format(),
	}),
  },
  hideInTable: true,
},

golang 导出 utc 时间转换为本地时间

v.Time.Local().Format("2006-01-02 15:04:05")

否则直接用 v.Time.Format("2006-01-02 15:04:05") 会显示为 0 时区的时间。会引起 bug。

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式