date-fns Time Zone Support
date-fns-tz provides robust time zone functionality for date-fns v3 and v4, leveraging the browser's native `Intl` API to avoid bundling large time zone data files. The current stable version is 3.2.0. This library is designed to work seamlessly with `date-fns`'s immutable `Date` object approach, offering functions like `formatInTimeZone` to format dates in a specified IANA time zone, and conversion utilities such as `toZonedTime` and `fromZonedTime` for shifting dates between UTC and specific time zones. It is a peer dependency of `date-fns`, requiring a compatible version (`^3.0.0 || ^4.0.0`). Its release cadence is tied to major `date-fns` versions, with minor updates for features and bug fixes. Key differentiators include its lightweight nature due to `Intl` API reliance and its adherence to the `date-fns` philosophy of pure functions and native Date objects.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'formatToParts')
cause The `Intl.DateTimeFormat` API is not available or incomplete in the current JavaScript environment.fixEnsure the runtime environment supports `Intl.DateTimeFormat` or include a polyfill (e.g., `@formatjs/intl-datetimeformat`). -
Error: date-fns-tz is an ESM-only package and cannot be used in CommonJS. (Or similar import/require errors)
cause Incorrect import statement or module resolution configuration for a hybrid ESM/CJS package.fixWhile `date-fns-tz` supports both CJS and ESM via `exports` field, ensure your `package.json` `type` field is correctly set to `module` for ESM projects or `commonjs` for CJS projects. Use `import { func } from 'date-fns-tz'` for ESM and `const { func } = require('date-fns-tz')` for CJS. -
TypeError: (0 , date_fns_tz__WEBPACK_IMPORTED_MODULE_3__.utcToZonedTime) is not a function
cause Attempting to use the old `utcToZonedTime` or `zonedTimeToUtc` function name after upgrading to v3.0.0+.fixUpdate the function call to the new names: `toZonedTime` and `fromZonedTime`. -
TypeError: (0 , date_fns_tz__WEBPACK_IMPORTED_MODULE_3__.default) is not a function (or similar error indicating default import issue)
cause Attempting to use a default import for a function that is exported as a named export.fixChange the import statement to use named exports: `import { functionName } from 'date-fns-tz';` (for ESM) or `const { functionName } = require('date-fns-tz');` (for CommonJS).
Warnings
- breaking date-fns-tz v3.0.0 removed support for date-fns v2. Ensure your project uses date-fns v3 or v4.
- breaking Functions `utcToZonedTime` and `zonedTimeToUtc` were renamed to `toZonedTime` and `fromZonedTime` respectively in v3.0.0.
- breaking All functions are now exported using named exports (ESM style) since v3.0.0, even for CommonJS. Direct default imports or destructuring from `require('date-fns-tz')` for CommonJS will fail if not using named exports.
- gotcha This library relies on the browser's native `Intl` API for time zone resolution. Older browsers or environments (like certain Node.js versions or custom builds) might require a polyfill for `Intl.DateTimeFormat`.
- gotcha The `date-fns` dependency is a peer dependency. You must install `date-fns` separately and ensure its version is compatible with `date-fns-tz`.
Install
-
npm install date-fns-tz -
yarn add date-fns-tz -
pnpm add date-fns-tz
Imports
- formatInTimeZone
const { formatInTimeZone } = require('date-fns-tz')import { formatInTimeZone } from 'date-fns-tz' - toZonedTime
import { utcToZonedTime } from 'date-fns-tz'import { toZonedTime } from 'date-fns-tz' - fromZonedTime
import { zonedTimeToUtc } from 'date-fns-tz'import { fromZonedTime } from 'date-fns-tz' - format
import { format } from 'date-fns-tz'
Quickstart
import { formatInTimeZone, toZonedTime } from 'date-fns-tz';
import { parseISO, format } from 'date-fns';
const dateString = '2024-04-21T18:30:00Z'; // UTC date string
const timeZone = 'America/Los_Angeles';
// Parse the ISO string to a Date object (which will be in UTC internally)
const utcDate = parseISO(dateString);
// Format the UTC date directly into the target timezone
const formattedTimeInLA = formatInTimeZone(utcDate, timeZone, 'yyyy-MM-dd HH:mm:ss zzz');
// Convert the UTC date to a Zoned Date object (representing local time in LA)
const zonedDateInLA = toZonedTime(utcDate, timeZone);
// Format the zoned date using date-fns's format (since it's now a 'local' date in LA)
const formattedZonedDate = format(zonedDateInLA, 'yyyy-MM-dd HH:mm:ss');
console.log(`Original UTC: ${dateString}`);
console.log(`Formatted in ${timeZone} (with timezone token): ${formattedTimeInLA}`);
console.log(`Zoned Date in ${timeZone}: ${zonedDateInLA.toISOString()}`); // Shows as if local time, but internally still UTC
console.log(`Formatted Zoned Date in ${timeZone}: ${formattedZonedDate}`);