如何用date-fns-tz将指定时区的时间戳转为UTC时间?
更简洁的无时区时间转指定时区Unix时间戳方案
我需要把一个不带时区信息的时间字符串,当作某一特定时区的时间来处理,最终获取对应的UTC Unix时间戳——注意,不是把当前时区的时间转换到目标时区,而是将给定时间归属到目标时区后,再转成对应的UTC时间戳。
举个例子:我当前处于Europe/Amsterdam时区,要把2023-09-26 00:00:00当作America/New_York时区的时间,算出对应的Unix戳。之前我用了一套绕弯的方法,步骤繁琐:
const stamp = '2023-09-26 00:00:00'; // 时间正确但时区错误 const wrongTz = dateFns.parse(stamp, 'yyyy-MM-dd HH:mm:ss', new Date()); // 时间和时区正确,但Unix戳错误 const rightTzWrongUnix = dateFnsTz.toDate(wrongTz, { timeZone, locale }); // 生成带目标时区偏移的时间字符串 const stampWithTz = dateFnsTz.format(rightTzWrongUnix, 'yyyy-MM-dd HH:mm:ss XX', { locale, timeZone }); // 解析成正确的UTC时间 const finalDate = new Date(stampWithTz); // 得到正确的Unix戳 console.log(getUnixTime(finalDate)) // >> 1695700800,对应UTC的2023-09-26 04:00:00
更优方案:用zonedTimeToUtc一步到位
date-fns-tz提供了zonedTimeToUtc方法,专门用来将指定时区的时间字符串直接转换为对应的UTC Date对象,内部会自动处理夏令时等时区偏移问题,完全不需要中间的格式转换步骤:
const { getUnixTime } = require('date-fns'); const { zonedTimeToUtc } = require('date-fns-tz'); const stamp = '2023-09-26 00:00:00'; const targetTimeZone = 'America/New_York'; // 直接将字符串解析为目标时区的时间,返回对应的UTC Date对象 const utcDate = zonedTimeToUtc(stamp, targetTimeZone, { format: 'yyyy-MM-dd HH:mm:ss' }); const unixTimestamp = getUnixTime(utcDate); console.log(unixTimestamp); // 输出 1695700800
这个方法的逻辑更直接:告诉方法“我输入的字符串是targetTimeZone时区的时间”,它就会直接算出对应的UTC时间,不需要额外处理中间对象,代码更简洁也更不容易出错。
原生JS替代方案(不依赖库)
如果不想依赖date-fns系列库,也可以用原生Intl.DateTimeFormat来处理,但步骤相对繁琐一些:
const stamp = '2023-09-26 00:00:00'; const targetTimeZone = 'America/New_York'; // 拆分时间字符串为年、月、日、时、分、秒 const [datePart, timePart] = stamp.split(' '); const [year, month, day] = datePart.split('-').map(Number); const [hour, minute, second] = timePart.split(':').map(Number); // 构造目标时区的格式化器 const formatter = new Intl.DateTimeFormat('en-US', { timeZone: targetTimeZone, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }); // 解析为UTC时间字符串并转Unix戳 const parts = formatter.formatToParts(new Date(Date.UTC(year, month - 1, day, hour, minute, second))); const utcDateStr = `${parts.find(p => p.type === 'year').value}-${parts.find(p => p.type === 'month').value}-${parts.find(p => p.type === 'day').value}T${parts.find(p => p.type === 'hour').value}:${parts.find(p => p.type === 'minute').value}:${parts.find(p => p.type === 'second').value}Z`; const unixTimestamp = new Date(utcDateStr).getTime() / 1000; console.log(unixTimestamp); // 输出 1695700800
内容的提问来源于stack exchange,提问作者douliman
相关产品推荐
相关产品推荐

