Skip to content

v4 开始,date-fns 对时区提供了一流的支持。

它通过 @date-fns/tz@date-fns/utc 包提供。

访问链接以了解有关相应包的更多信息。

date-fns 中的其他内容一样,时区支持具有最小的捆绑包大小占用空间,UTCDateMiniTZDateMini 分别为 239B761B

如果您正在寻找 date-fns v4 之前的时区支持,请参阅第三方 date-fns-tz 包。

使用时区:

有两种方法可以开始使用时区。

  • 使用日期扩展 TZDateUTCDate
  • 使用选项中的 date-fns 函数。

使用 TZDate 和 UTCDate

一种方法是使用 TZDateUTCDate 日期扩展,并结合常规 date-fns 函数:

javascript
import { TZDate } from '@date-fns/tz';
import { addHours } from 'date-fns';

// 假设系统时区为 America/Los_Angeles
// 夏令时于 2022 年 3 月 13 日星期日 02:00:00 开始

// 由于夏令时 (DST),使用系统时区将产生 03:00 而不是 02:00:
const date = new Date(2022, 2, 13);
addHours(date, 2).toString();
//=> 'Sun Mar 13 2022 03:00:00 GMT-0700 (Pacific Daylight Time)'

// 使用亚洲/新加坡将提供预期的 02:00:
const tzDate = new TZDate(2022, 2, 13, 'Asia/Singapore');
addHours(tzDate, 2).toString();
//=> 'Sun Mar 13 2022 02:00:00 GMT+0800 (Singapore Standard Time)'

您可以安全地混合和匹配常规 Date 实例,以及不同时区和原始值 (时间戳和字符串) 的 UTCDate 或 TZDate。

date-fns 将规范化参数,以第一个对象参数 (Date 或 Date 扩展实例) 作为引用并以引用类型返回结果:

javascript
import { TZDate } from '@date-fns/tz';
import { differenceInBusinessDays } from 'date-fns';

const laterDate = new TZDate(2025, 0, 1, 'Asia/Singapore');
const earlierDate = new TZDate(2024, 0, 1, 'America/New_York');

// 将以 Asia/Singapore 时区计算
differenceInBusinessDays(laterDate, earlierDate);
//=> 262

// 将以 America/New_York 时区计算
differenceInBusinessDays(earlierDate, laterDate);
//=> -261

在给定的例子中,一天的差异来自于纽约 (UTC-5) 的事实,earlyDate12月31日 而不是 1月1日

javascript
laterDate.withTimeZone('Asia/Singapore').toString();
//=> 'Wed Jan 01 2025 00:00:00 GMT+0800 (Singapore Standard Time)'
earlierDate.withTimeZone('Asia/Singapore').toString();
//=> 'Mon Jan 01 2024 13:00:00 GMT+0800 (Singapore Standard Time)'

laterDate.withTimeZone('America/New_York').toString();
//=> 'Tue Dec 31 2024 11:00:00 GMT-0500 (Eastern Standard Time)'
earlierDate.withTimeZone('America/New_York').toString();
//=> 'Mon Jan 01 2024 00:00:00 GMT-0500 (Eastern Standard Time)'

在进行计算时理解和考虑这一点至关重要。

在选项中使用

当获取特定时区中的值很重要或者不确定参数的类型时,请使用选项中的函数上下文。

每个函数的计算都可能受到时区的影响,例如 differenceInBusinessDays,它接受 in 选项,该选项为参数和结果提供上下文,因此您可以明确说明要使用的时区:

javascript
import { tz } from '@date-fns/tz';

// 将以 Asia/Singapore 时区计算
differenceInBusinessDays(laterDate, earlierDate);
//=> 262

// 将以 America/New_York 时区计算
differenceInBusinessDays(laterDate, earlierDate, {
    in: tz('America/Los_Angeles')
});
//=> 261

在示例中,我们强制 differenceInBusinessDays 使用洛杉矶时区。

何以解忧,唯有代码。不忘初心,方得始终。