根据指定时区转换UTC时间出现2小时偏差,求技术支持
时区转换问题排查与解决
问题背景
数据库所有记录以UTC时间存储:
createdAt: 2022-11-28T23:58:29.670Z createdAt: 2022-11-29T00:13:23.213Z createdAt: 2022-11-29T05:11:22.113Z
需要筛选America/Santo_Domingo时区2022-11-29当天的记录,第一步要把该时区的当天零点转成UTC时间,预期结果是2022-11-29T04:00:00.000Z,但现有dayjs代码输出结果差了2小时。
现有代码及问题
const UTC = dayjs(date + 'T00:00:00Z'); // 得到2022-11-29T00:00:00.000Z
const timeWithTimezone = UTC.tz(tz); // 实际得到2022-11-28T18:00:00.000Z,预期为2022-11-28T20:00:00.000Z
const UTCwithOffset = UTC.utcOffset(timeWithTimezone.utcOffset()*-1); // 实际得到2022-11-29T02:00:00.000Z,带有信息 '$x': { '$localOffset': -120 }
问题原因
- 时间构造方向搞反:你直接把
2022-11-29拼接成UTC零点时间,但实际需要的是America/Santo_Domingo时区的当地零点,再转成UTC。 - tz方法用反了:
UTC.tz(tz)是把UTC时间转成目标时区的本地时间,而不是把目标时区时间转成UTC。按逻辑,UTC的2022-11-29零点转成America/Santo_Domingo时区应该是2022-11-28 20:00(该时区当时为UTC-4),但你得到18:00,大概率是因为dayjs没正确加载该时区的最新数据,或者时区数据过时。 - 手动偏移逻辑错误:通过取反偏移量来转换的方式不可靠,忽略了时区的夏令时/标准时动态变化,容易计算出错。
正确实现代码
先确保已安装并导入dayjs的必要插件:
import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; import timezone from 'dayjs/plugin/timezone'; dayjs.extend(utc); dayjs.extend(timezone);
然后直接构造目标时区的当地时间再转UTC:
// 构造America/Santo_Domingo时区的2022-11-29 00:00:00 const localStart = dayjs.tz('2022-11-29T00:00:00', 'America/Santo_Domingo'); // 转换为UTC时间 const utcStart = localStart.utc(); console.log(utcStart.format()); // 输出:2022-11-29T04:00:00Z,符合预期
筛选记录的后续逻辑
得到UTC起始时间2022-11-29T04:00:00Z后,再计算该时区当天结束时间对应的UTC(即2022-11-30T04:00:00Z),然后筛选数据库中createdAt大于等于起始UTC且小于结束UTC的记录即可。
内容的提问来源于stack exchange,提问作者Mediator
相关产品推荐
相关产品推荐

