如何用date-fns将日期转为UTC并按日递减以规避夏令时问题
基于date-fns的UTC日期循环解决方案
问题背景
需要从当前日期反向迭代至2022年10月1日,按24小时窗口调用API查询数据,但因英国夏令时切换(10月31日),原本地日期逻辑会出现时间窗口超出24小时的问题。要求改用UTC日期逻辑,忽略时区和夏令时影响,优先使用date-fns实现。
解决方案代码
import { startOfDayUTC, subDays, isGreaterThanOrEqualTo, parseISO } from 'date-fns'; import axios, { AxiosResponse, AxiosError } from 'axios'; export async function dataTrawl(): Promise<void> { try { // 定义目标起始日期(UTC时区的2022-10-01 00:00:00) const targetStartDate = parseISO('2022-10-01T00:00:00Z'); // 初始化当前日期为UTC当天的起始时间 let currentUTCDate = startOfDayUTC(new Date()); // 循环:当前UTC日期不早于目标起始日期时继续 while (isGreaterThanOrEqualTo(currentUTCDate, targetStartDate)) { // 每个查询窗口为:前一天UTC起始 -> 当前UTC起始(精确24小时) const startTime = subDays(currentUTCDate, 1); const endTime = currentUTCDate; const response: AxiosResponse<DataExchangeResponse> = await axios.get( '...api.../1/datapoints', { headers: { accept: 'application/json', 'x-api-key': 'KEY' }, params: { start: startTime.toISOString(), end: endTime.toISOString() } } ); console.log(`dataTrawl: ${JSON.stringify(response.data)}`); // 按UTC往前推移一天 currentUTCDate = subDays(currentUTCDate, 1); } } catch (e) { const error = e as AxiosError; console.error(error); } }
核心改动说明
- UTC日期定位:使用
startOfDayUTC获取UTC时区下当天的00:00:00,彻底规避本地时区和夏令时的干扰 - 精确日期递减:通过
subDays基于UTC日期往前减一天,保证每次迭代的时间跨度严格为24小时 - 明确目标日期:用
parseISO解析带Z标识的UTC日期字符串,确保目标起始日期的时区一致性 - 可靠循环判断:使用date-fns的
isGreaterThanOrEqualTo进行日期比较,比原生Date的比较更严谨,避免时区导致的逻辑错误
内容的提问来源于stack exchange,提问作者cien
相关产品推荐
相关产品推荐

