如何在JavaScript中为日期的初始时区设置指定小时?
问题
我在时区为+03:00的服务器上收到日期字符串:
2022-10-24T00:00:00+05:00
需要将其小时固定设置为上午8点,得到结果:
2022-10-24T08:00:00+05:00
该结果转换为服务器时区后应为2022-10-24T06:00:00+03:00。
目前直接创建Date对象后设置小时会被转成服务器时区的时间(比如得到2022-10-24T08:00:00+03:00),求用Date对象或Moment实现需求且不直接修改字符串的方法。
一、原生Date对象实现
核心是先拿到原日期的时区偏移,基于原时区的时间维度设置8点,再重构带时区的字符串:
const inputStr = '2022-10-24T00:00:00+05:00'; const date = new Date(inputStr); // 获取原日期的时区偏移(单位:分钟,+05:00对应300分钟) const originalOffset = date.getTimezoneOffset() * -1; const offsetHours = Math.floor(originalOffset / 60); const offsetMinutes = originalOffset % 60; // 构建原时区下8点的UTC时间 const targetUtc = new Date( date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 8 + offsetHours, offsetMinutes, 0, 0 ); // 输出原时区格式的目标字符串 const targetStr = targetUtc.toISOString().replace('Z', `${offsetHours >=0 ? '+' : ''}${String(offsetHours).padStart(2, '0')}:${String(offsetMinutes).padStart(2, '0')}`); console.log(targetStr); // 2022-10-24T08:00:00+05:00 // 转换为服务器时区(+03:00)的字符串 const serverOffset = 180; // +03:00对应180分钟 const serverDate = new Date(targetUtc.getTime() + (serverOffset - originalOffset) * 60 * 1000); console.log(serverDate.toISOString().replace('Z', '+03:00')); // 2022-10-24T06:00:00+03:00
逻辑说明:
getTimezoneOffset()返回的是UTC与本地时间的差值,取反后得到原时区相对于UTC的偏移量。- 基于原日期的UTC年月日,加上原时区偏移来设置8点,这样得到的UTC时间正好对应原时区的8点。
- 最后把ISO字符串的
Z替换成原时区偏移,得到目标格式。
二、Moment.js(搭配moment-timezone)实现
用Moment处理时区更省心,无需手动计算偏移:
const moment = require('moment-timezone'); const inputStr = '2022-10-24T00:00:00+05:00'; // 解析原日期并保留其时区信息 const originalMoment = moment.parseZone(inputStr); // 在原时区下直接设置小时为8,分钟、秒归零 const targetMoment = originalMoment.hour(8).minute(0).second(0); // 输出原时区格式的目标字符串 const targetStr = targetMoment.format(); console.log(targetStr); // 2022-10-24T08:00:00+05:00 // 转换为服务器时区(+03:00)的字符串 const serverMoment = targetMoment.tz('Etc/GMT-3'); // Etc/GMT-3对应+03:00 console.log(serverMoment.format()); // 2022-10-24T06:00:00+03:00
逻辑说明:
moment.parseZone()会保留原日期的时区偏移,不会自动转成服务器本地时区。- 调用
hour(8)修改的是原时区下的小时数,完全不受服务器时区影响。 - 用
tz()方法直接切换到服务器时区,输出对应格式即可。
内容的提问来源于stack exchange,提问作者Flo
相关产品推荐
相关产品推荐

