使用moment.js Timezone设置起始时区并转换至其他时区遇问题
问题描述
我参考示例使用moment.js Timezone时未得到预期结果:
- 起始时间字符串设为
2023-03-05 08:00:00,希望将其视为**墨西哥城(CST)**时间 - 尝试转换为纽约(EST)和洛杉矶(PST)时间,预期结果应为:09:00 EST、06:00 PST
- 实际得到:08:00 EST、05:00 PST
- 本地处于EST时区,疑惑是否无法在EST环境下将起始时间设置为CST?
原代码如下:
var startDateAndTimeString = '2023-03-05 08:00:00'; // CST var startDateAndTime = moment(startDateAndTimeString).tz('America/Mexico_City'); function formatDateToAnotherTimezone(anotherTimezone, startDateAndTime) { return moment(startDateAndTime).tz(anotherTimezone).format('ha z'); } var est = formatDateToAnotherTimezone('America/New_York',startDateAndTime); var pst = formatDateToAnotherTimezone('America/Los_Angeles',startDateAndTime); console.log(est) console.log(pst)
引入的脚本:
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.min.js"></script>
问题原因与解决办法
核心问题
你的代码初始化时区的方式错误:moment(startDateAndTimeString).tz('America/Mexico_City') 会先把字符串按照本地时区(EST)解析成时间,再转换为墨西哥城时区,这完全违背了你的需求——你需要的是把字符串直接当作墨西哥城时区的时间来解析。
修正方案
- 改用
moment.tz()直接解析指定时区的时间字符串,而非先解析本地时间再转时区 - 转换时区时,无需用
moment()重新包裹已有的moment时区对象,直接调用.tz()即可
修正后的代码:
var startDateAndTimeString = '2023-03-05 08:00:00'; // 直接将字符串解析为墨西哥城时区的时间 var startDateAndTime = moment.tz(startDateAndTimeString, 'America/Mexico_City'); function formatDateToAnotherTimezone(anotherTimezone, startDateAndTime) { // 直接对已有的时区对象调用tz()转换 return startDateAndTime.tz(anotherTimezone).format('ha z'); } var est = formatDateToAnotherTimezone('America/New_York', startDateAndTime); var pst = formatDateToAnotherTimezone('America/Los_Angeles', startDateAndTime); console.log(est); // 输出:9am EST console.log(pst); // 输出:6am PST
说明
moment.tz(时间字符串, 时区标识)是moment-timezone中正确解析指定时区时间的方式,它会忽略本地时区,直接把字符串对应到目标时区的时间点- 已创建的带时区的moment对象,直接调用
.tz(目标时区)就能完成转换,不需要重新实例化moment对象
内容的提问来源于stack exchange,提问作者Rich
相关产品推荐
相关产品推荐

