You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算JavaScript中指定日期的当日首尾时间戳?

如何正确获取Date对象的当日起止时间(规避时区干扰)

问题描述

给定一个JavaScript Date对象,想要获取该日期本地时区的当日开始时间(如2024-01-16 00:00)和结束时间(2024-01-16 23:59),但使用date-fns的startOfDay、endOfDay方法后得到的UTC格式输出与预期不符:

测试代码

import { addDays, addHours, endOfDay, startOfDay, subHours } from 'date-fns';

// d = new Date(...) 实际对应本地时间2024-01-16 22:35,UTC时间为2024-01-16T17:00:00.000Z
const hoursBefore = 12;
const hoursAfter = 5;
const startDate = subHours(startOfDay(d), hoursBefore);
const endDate = addHours(endOfDay(d), hoursAfter);

console.log('Date: ', d);
console.log('Start Of Day: ', startOfDay(d));
console.log('End Of Day: ', endOfDay(d));
console.log('startDate: ', startDate);
console.log('endDate: ', endDate);

输出结果

Date:  2024-01-16T17:00:00.000Z
Start Of Day:  2024-01-16T17:00:00.000Z
End Of Day:  2024-01-17T16:59:59.999Z
startDate:  2024-01-16T05:00:00.000Z
endDate:  2024-01-17T21:59:59.999Z

原因分析

完全是时区差异导致的误解:

  • date-fns的startOfDay、endOfDay方法默认基于本地时区计算当日起止时间。
  • 控制台打印Date对象时,默认输出UTC格式的字符串(带Z后缀),而非本地时间。比如你的本地时区为UTC+5(2024-01-16T17:00:00.000Z对应本地时间2024-01-16 22:00),所以startOfDay(d)对应的本地时间是2024-01-16 00:00,转换为UTC就是2024-01-16T17:00:00.000Z,和你看到的输出一致。

解决方案

根据实际需求选择对应方法:

1. 获取本地时区的当日起止时间

如果要确认结果正确,可使用toLocaleString()输出本地时间,或用date-fns的format方法格式化:

import { endOfDay, startOfDay, format } from 'date-fns';

const d = new Date('2024-01-16T17:00:00.000Z');
const localStartOfDay = startOfDay(d);
const localEndOfDay = endOfDay(d);

// 输出本地时间格式
console.log('本地当日开始:', format(localStartOfDay, 'yyyy-MM-dd HH:mm:ss')); // 2024-01-16 00:00:00
console.log('本地当日结束:', format(localEndOfDay, 'yyyy-MM-dd HH:mm:ss')); // 2024-01-16 23:59:59

2. 获取UTC时区的当日起止时间

如果需要UTC时区的当日00:00到23:59,使用date-fns专门的UTC版本方法(从date-fns/utc导入):

import { endOfDayUTC, startOfDayUTC } from 'date-fns/utc';
import { format } from 'date-fns';

const d = new Date('2024-01-16T17:00:00.000Z');
const utcStartOfDay = startOfDayUTC(d);
const utcEndOfDay = endOfDayUTC(d);

console.log('UTC当日开始:', utcStartOfDay); // 2024-01-16T00:00:00.000Z
console.log('UTC当日结束:', utcEndOfDay); // 2024-01-16T23:59:59.999Z
// 格式化输出UTC时间
console.log('UTC当日开始(格式化):', format(utcStartOfDay, 'yyyy-MM-dd HH:mm:ss', { timeZone: 'UTC' }));

3. 修正原代码的时区问题

如果hoursBefore和hoursAfter是基于本地时区调整,先处理本地时区的起止再调整小时:

import { addHours, endOfDay, startOfDay, subHours, format } from 'date-fns';

const d = new Date('2024-01-16T17:00:00.000Z');
const hoursBefore = 12;
const hoursAfter = 5;

// 先获取本地当日起止,再调整小时
const localStart = startOfDay(d);
const startDate = subHours(localStart, hoursBefore);
const localEnd = endOfDay(d);
const endDate = addHours(localEnd, hoursAfter);

// 用本地格式输出验证
console.log('调整后的开始:', format(startDate, 'yyyy-MM-dd HH:mm:ss'));
console.log('调整后的结束:', format(endDate, 'yyyy-MM-dd HH:mm:ss'));

内容的提问来源于stack exchange,提问作者delete

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 03:34:58