如何用date-fns-tz获取指定时区到次日的毫秒数?
计算指定时区下距离次日午夜的毫秒数
需要实现一个函数,根据指定时区计算当前时间到次日午夜的毫秒数,当当前时间恰好为该时区的午夜时返回0,用于触发订阅或React状态更新。函数签名如下:
function millisecondsBeforeNextDay(now: number| Date, timeZone: string) : number {}
实现方案
核心思路是基于指定时区解析当前时间的时分秒毫秒,计算当日已流逝的毫秒数,再用一天的总毫秒数减去该值;若已流逝毫秒数为0(即当前是午夜),则直接返回0。
function millisecondsBeforeNextDay(now: number | Date, timeZone: string): number { // 将输入统一转为Date对象 const currentDate = typeof now === 'number' ? new Date(now) : new Date(now.getTime()); // 配置Intl格式化器,获取指定时区的时分秒毫秒 const formatter = new Intl.DateTimeFormat('en-US', { timeZone, hour: '2-digit', minute: '2-digit', second: '2-digit', fractionalSecondDigits: 3, hour12: false }); // 解析出时间组件 const parts = formatter.formatToParts(currentDate); const hour = parseInt(parts.find(p => p.type === 'hour')?.value || '0', 10); const minute = parseInt(parts.find(p => p.type === 'minute')?.value || '0', 10); const second = parseInt(parts.find(p => p.type === 'second')?.value || '0', 10); const millisecond = parseInt(parts.find(p => p.type === 'fractionalSecond')?.value || '0', 10); // 计算当日已流逝的毫秒数 const elapsedMs = hour * 3600000 + minute * 60000 + second * 1000 + millisecond; // 若已流逝毫秒为0(午夜)则返回0,否则返回剩余毫秒 return elapsedMs === 0 ? 0 : 86400000 - elapsedMs; }
代码说明
- 输入兼容:同时支持时间戳(number类型)和Date对象作为输入
- 时区精准性:通过
Intl.DateTimeFormat强制使用指定时区解析时间,避免本地时区干扰 - 边界处理:当当前时间恰好是指定时区的午夜时,直接返回0,而非24小时对应的毫秒数
- 计算逻辑:通过时分秒毫秒计算当日已过时长,再用一天总毫秒数(86400000)减去该值,得到距离次日午夜的毫秒数
使用示例
以下是在React钩子中使用该函数的场景,用于每日更新状态:
export function useDayClockState(): Date { const defaultCalendar = Localization.getCalendars()[0]; const now = useClockState(24 * 60 * 60 * 1000, millisecondsBeforeNextDay(Date.now(), defaultCalendar.timeZone!)); return now; }
内容的提问来源于stack exchange,提问作者Archimedes Trajano
相关产品推荐
相关产品推荐

