@date-fns/tz
The package provides Date extensions TZDate and TZDateMini that perform all calculations in the given time zone rather than the system time zone.
Using it makes date-fns operate in given time zone but can also be used without it.
Like everything else in the date-fns ecosystem, the library is build-size aware. The smallest component, TZDateMini, is only 916 B.
Need only UTC? See @date-fns/utc that provides lighter solution.
Installation
npm install @date-fns/tz --save
Usage
TZDate and TZDateMini have API similar to Date, but perform all calculations in the given time zone, which might be essential when operating across different time zones, calculating dates for users in different regions, or rendering chart or calendar component:
import { TZDate } from "@date-fns/tz";
import { addHours } from "date-fns";
const date = new Date(2022, 2, 13);
addHours(date, 2).toString();
const tzDate = new TZDate(2022, 2, 13, "Asia/Singapore");
addHours(tzDate, 2).toString();
Accepted time zone formats
You can pass IANA time zone name ("Asia/Singapore", "America/New_York", etc.) or UTC offset ("+01:00", "-2359", or "+23"):
new TZDate(2022, 2, 13, "Asia/Singapore");
new TZDate(2022, 2, 13, "+08:00");
new TZDate(2022, 2, 13, "-2359");
Difference between TZDate and TZDateMini
The main difference between TZDate and TZDateMini is the build footprint. The TZDateMini is 916 B, and the TZDate is 1.2 kB. While the difference is slight it might be essential in some environments and use cases.
Unlike TZDateMini which implements only getters, setters, and getTimezoneOffset, TZDate also provides formatter functions, mirroring all original Date functionality:
import { TZDateMini, TZDate } from "@date-fns/tz";
new TZDateMini(2022, 2, 13).toString();
new TZDate(2022, 2, 13).toString();
Even though TZDate has a complete API, developers rarely use the formatter functions outside of debugging, so we recommend you pick the more lightweight TZDateMini for internal use. However, in environments you don't control, i.e., when you expose the date from a library, using TZDate will be a safer choice.
React Native / Hermes JS Engine
Starting with v1.3.0, @date-fns/tz supports Format.JS polyfills that are required for Hermes JS Engine powering React Native runtime to work correctly.
To use it, you need to import the following polyfills in your entry point:
import "@formatjs/intl-getcanonicallocales/polyfill";
import "@formatjs/intl-locale/polyfill";
import "@formatjs/intl-pluralrules/polyfill";
import "@formatjs/intl-numberformat/polyfill";
import "@formatjs/intl-numberformat/locale-data/en";
import "@formatjs/intl-datetimeformat/polyfill";
import "@formatjs/intl-datetimeformat/locale-data/en";
import "@formatjs/intl-datetimeformat/add-golden-tz";
The JavaScriptCore engine is also supported and tested but does not require any polyfills.
API
TZDate
All the TZDate docs are also true for TZDateMini.
Constructor
When creating TZDate, you can pass the time zone as the last argument:
new TZDate(2022, 2, "Asia/Singapore");
new TZDate(timestamp, "Asia/Singapore");
new TZDate("2024-09-12T00:00:00Z", "Asia/Singapore");
The constructor mirrors the original Date parameters except for the last time zone parameter.
TZDate.tz
The static tz function allows to construct TZDate instance with just a time zone:
TZDate.tz("Asia/Singapore");
new TZDate("Asia/Singapore");
Just like the constructor, the function accepts all parameters variants:
TZDate.tz("Asia/Singapore", 2022, 2);
TZDate.tz("Asia/Singapore", timestamp);
TZDate.tz("Asia/Singapore", "2024-09-12T00:00:00Z");
timeZone
The readonly timeZone property returns the time zone name assigned to the instance:
new TZDate(2022, 2, 13, "Asia/Singapore").timeZone;
The property might be undefined when created without a time zone:
new TZDate().timeZone;
withTimeZone
The withTimeZone method allows to create a new TZDate instance with a different time zone:
const sg = new TZDate(2022, 2, 13, "Asia/Singapore");
const ny = sg.withTimeZone("America/New_York");
sg.toString();
ny.toString();
[Symbol.for("constructDateFrom")]
The TZDate instance also exposes a method to construct a Date instance in the same time zone:
const sg = TZDate.tz("Asia/Singapore");
const date = sg[Symbol.for("constructDateFrom")](new Date(2024, 0, 1));
date.toString();
It's created for date-fns but can be used in any context. You can access it via Symbol.for("constructDateFrom") or import it from the package:
import { constructFromSymbol } from "@date-fns/tz";
tz
The tz function allows to specify the context for the [date-fns] functions (starting from date-fns@4):
import { isSameDay } from "date-fns";
import { tz } from "@date-fns/tz";
isSameDay("2024-09-09T23:00:00-04:00", "2024-09-10T10:00:00+08:00", {
in: tz("Europe/Prague"),
});
tzOffset
The tzOffset function allows to get the time zone UTC offset in minutes from the given time zone and a date:
import { tzOffset } from "@date-fns/tz";
const date = new Date("2020-01-15T00:00:00Z");
tzOffset("Asia/Singapore", date);
tzOffset("America/New_York", date);
tzOffset("America/New_York", "2020-01-15T00:00:00Z");
Unlike Date.prototype.getTimezoneOffset, this function returns the value mirrored to the sign of the offset in the time zone. For Asia/Singapore (UTC+8), tzOffset returns 480, while getTimezoneOffset returns -480.
tzScan
The function scans the time zone for changes in the given interval. It returns an array of objects with the date of the change, the offset change, and the new offset:
import { tzScan } from "@date-fns/tz";
tzScan("America/New_York", {
start: new Date("2020-01-01T00:00:00Z"),
end: new Date("2024-01-01T00:00:00Z"),
});
tzName
The function returns time zone name in human-readable format, e.g. "Singapore Standard Time" in the give date and time.
import { tzName } from "@date-fns/tz";
tzName("Asia/Singapore", new Date("2020-01-01T00:00:00Z"));
It is possible to specify the format as the third argument using one of the following options:
"short"e.g., "EDT" or "GMT+8"`.
"long": e.g., "Eastern Daylight Time" or "Singapore Standard Time".
"shortGeneric": e.g., "ET" or "Singapore Time".
"longGeneric": e.g., "Eastern Time" or "Singapore Standard Time".
These options correspond to TR35 tokens z..zzz, zzzz, v, and vvvv respectively.
import { tzName } from "@date-fns/tz";
const date = new Date("2020-01-01T00:00:00.000Z");
tzName("America/New_York", date, "short");
tzName("America/New_York", date, "shortGeneric");
Changelog
See the changelog.
License
MIT © Sasha Koss