使用moment-timezone转换时区异常求助:无法获取目标时区时间
问题描述
我希望使用moment-timezone库,将用户选择的时间转换为其资料中保存的时区。本地系统时区为PKT(巴基斯坦时区),用户资料中保存的时区为AEST(澳大利亚悉尼时区)。当用户选择时间后,我需要得到该时间对应的AEST时区时间并传入API,但使用moment-timezone的多种写法均未得到预期结果(预期为AEST的7点,实际得到其他时间)。若moment无法支持该需求,希望推荐其他可用库。
测试代码如下:
const time = "07:00" const date = "06/13/2023" const timezone = "Australian/Sydney" moment(`${date} ${time}`).tz(timezone).format() // 2023-06-20T12:00:00+10:00
const time = "07:00" const date = "06/13/2023" const timezone = "Australian/Sydney" moment.tz.setDefault(timezone) moment(`${date} ${time}`).tz(timezone).format() //2023-06-20T12:00:00+10:00 moment(`${date} ${time}`).format() //2023-06-20T12:00:00+10:00 moment.tz(`${date} ${time}`, timezone).format() // 2023-06-20T17:00:00+10:00
问题分析与解决办法
核心问题
你的代码逻辑错误在于:
- 直接调用
moment(${date} ${time})时,moment会默认将这个时间字符串解析为**本地系统时区(PKT)**的时间,再转换为目标时区(AEST),所以得到的是PKT时间对应的AEST时间,而非你预期的“AEST时区的7点”。 - 最后用的
moment.tz(${date} ${time}, timezone)写法方向正确,但未指定明确的解析格式,moment可能误判日期格式(比如把06/13/2023当成DD/MM/YYYY而非MM/DD/YYYY),导致解析出错误时间。
正确写法
分两种场景处理:
用户选择的时间本身就是AEST时区的07:00
明确告诉moment输入的日期时间属于目标时区,同时指定解析格式避免歧义:const time = "07:00" const date = "06/13/2023" const timezone = "Australian/Sydney" // 指定解析格式为MM/DD/YYYY HH:mm,直接解析为AEST时区的时间 const aestTime = moment.tz(`${date} ${time}`, 'MM/DD/YYYY HH:mm', timezone).format() // 预期输出:2023-06-13T07:00:00+10:00用户选择的是PKT时区的07:00,需要转换为AEST时区时间
先解析为本地PKT时间,再转换到目标时区(这是你之前代码得到12:00的原因,PKT是UTC+5,AEST是UTC+10,PKT的7点对应AEST的12点,转换逻辑本身正确):const time = "07:00" const date = "06/13/2023" const timezone = "Australian/Sydney" const aestTime = moment(`${date} ${time}`, 'MM/DD/YYYY HH:mm').tz(timezone).format() // 输出:2023-06-13T12:00:00+10:00
替代库推荐
如果觉得moment-timezone的API不够直观,推荐以下两个现代日期库:
- date-fns-tz:轻量级时区处理库,基于date-fns生态,采用函数式编程风格,API简洁易懂。
- luxon:由moment团队开发的下一代日期库,原生支持时区,使用不可变对象设计,避免了moment的可变对象陷阱,API更符合现代JS规范。
内容的提问来源于stack exchange,提问作者Bilal Butt
相关产品推荐
相关产品推荐

