服务器为UTC时区时,如何在JS中获取本地时区当日起止时间?
本地时区当日起止时间戳获取问题解决
问题背景
服务器运行在UTC时区,需按Asia/Jakarta本地时区筛选数据,数据的collectTime为Unix时间戳。需要获取本地时区当日起止的Unix时间戳,但原有代码生成的结果与预期不符。
原有代码:
const { startOfDay, endOfDay, getTime, subDays } = require("date-fns"); const { utcToZonedTime } = require("date-fns-tz"); const timezone = "Asia/Jakarta"; const correctLocalStartDate = 1685379600000; const correctLocalEndDate = 1685465999999; const selectedUnixTime = subDays(new Date(), 1).getTime(); const localDate = utcToZonedTime(selectedUnixTime, timezone); const localStartDate = getTime(startOfDay(localDate)); const localEndDate = getTime(endOfDay(localDate)); console.log( { isItCorrect: localStartDate === correctLocalStartDate, correctDate: new Date(correctLocalStartDate), systemDate: new Date(localStartDate), }, "Start Date" ); console.log( { isItCorrect: localEndDate === correctLocalEndDate, correctDate: new Date(correctLocalEndDate), systemDate: new Date(localEndDate), }, "End Date" );
运行结果:
{ isItCorrect: false, correctDate: 2023-05-29T17:00:00.000Z, systemDate: 2023-05-30T07:00:00.000Z } // Start Date { isItCorrect: false, correctDate: 2023-05-30T16:59:59.999Z, systemDate: 2023-05-31T06:59:59.999Z } // End Date
解决方法
问题出在基于UTC时间计算目标日期,导致本地时区的日期偏移。正确流程应基于本地时区计算日期,再转成UTC时间戳:
const { startOfDay, endOfDay, getTime, subDays } = require("date-fns"); const { utcToZonedTime, zonedTimeToUtc } = require("date-fns-tz"); const timezone = "Asia/Jakarta"; const correctLocalStartDate = 1685379600000; // 对应Jakarta时区2023-05-30 00:00:00 const correctLocalEndDate = 1685465999999; // 对应Jakarta时区2023-05-30 23:59:59.999 // 1. 将当前UTC时间转成本地时区时间 const currentLocalTime = utcToZonedTime(new Date(), timezone); // 2. 获取本地时区的前一天(按需调整,若要当天则去掉subDays) const targetLocalDate = subDays(currentLocalTime, 1); // 3. 获取本地时区当日的起止时刻(本地时间的00:00和23:59:59.999) const localStart = startOfDay(targetLocalDate); const localEnd = endOfDay(targetLocalDate); // 4. 将本地时区的起止时刻转成UTC时间戳(Unix时间戳本质是UTC毫秒数) const localStartDate = getTime(zonedTimeToUtc(localStart, timezone)); const localEndDate = getTime(zonedTimeToUtc(localEnd, timezone)); console.log( { isItCorrect: localStartDate === correctLocalStartDate, correctDate: new Date(correctLocalStartDate), systemDate: new Date(localStartDate), localStartDisplay: new Date(localStart).toLocaleString('en-US', { timeZone: timezone }) }, "Start Date" ); console.log( { isItCorrect: localEndDate === correctLocalEndDate, correctDate: new Date(correctLocalEndDate), systemDate: new Date(localEndDate), localEndDisplay: new Date(localEnd).toLocaleString('en-US', { timeZone: timezone }) }, "End Date" );
关键说明
- 先转本地时区再计算目标日期:确保基于本地时间逻辑获取“昨天/当天”,避免UTC时间带来的偏移
- 用
zonedTimeToUtc转换起止时刻:Unix时间戳是UTC时间的毫秒数,需要把本地时区的起止时间转成对应的UTC时间再取戳
内容的提问来源于stack exchange,提问作者mandaputtra
相关产品推荐
相关产品推荐

