temporal-extra
v1.6.0
Published
Locale-aware date utilities for Temporal: week numbers, date adjusters, polyfill support and more
Downloads
1,416
Maintainers
Readme
temporal-extra
Locale-aware Temporal utilities for ISO week numbers, business day navigation, and calendar inspections. Built on top of the Temporal API, with optional polyfill support.
Features
- Adjusters: Jump to previous/next business day, week day, or boundary of a month/year.
- Comparators: Compare Temporal instances to reference.
- Polyfill support: Includes a tiny TypeScript-compatible Intl.Locale.getWeekInfo() polyfill.
Installation
Install via your favorite package manager:
npm install temporal-extra
# or
pnpm add temporal-extra
# or
yarn add temporal-extraUsing the Temporal Polyfill
If you want to use the Temporal API in environments where it is not yet natively supported, you can include the temporal-polyfill.
Once you have it installed, you can enable it:
if (typeof Temporal === "undefined") {
await import("temporal-polyfill/global");
}This will globally patch the environment, adding the Temporal API on globalThis.Temporal.
TypeScript support for Temporal
To get proper TypeScript typings for the polyfill (and the Temporal API in general), you need to install the temporal-spec types package.
Then create a temporal.d.ts file in your project (e.g., in your src folder or your types folder) with the
following content:
import "temporal-spec/global";This will augment the TypeScript global scope with Temporal API types, so your editor and compiler understand Temporal
properly.
Usage
Adjusters
Adjust or navigate PlainDate, PlainDateTime, or ZonedDateTime instances:
import {
previousBusinessDay,
nextDayOfWeek,
firstDayOfMonth,
lastDayOfYear,
FRIDAY,
} from "temporal-extra";
const date = Temporal.PlainDate.from("2024-06-18");
previousBusinessDay(date, "en-US"); // skips Sat/Sun
nextDayOfWeek(date, FRIDAY); // jump to next Friday
firstDayOfMonth(date); // 2024-06-01
lastDayOfYear(date); // 2024-12-31All functions are type-safe and maintain the input type (PlainDate, PlainDateTime, or ZonedDateTime).
Comparators
Check if a given temporal is before, equal or after another temporal:
import {
isBefore,
isBeforeOrEqual,
isAfter,
isAfterOrEqual,
} from "temporal-extra";
const date = Temporal.PlainDate.from("2024-06-18");
const reference = Temporal.PlainDate.from("2024-06-19");
isBefore(date, reference); // true
isBeforeOrEqual(date, reference); // false
isAfter(date, reference); // false
isAfterOrEqual(date, reference); // falseSupported types: Instant, PlainDate, PlainTime, PlainDateTime, PlainYearMonth, and ZonedDateTime. Both
values must be of the same type.
NOTE:
PlainMonthDayis intentionally unsupported: its ordering depends on the year. Convert both values toPlainDateviatoPlainDate({ year })with a year of your choosing.
Polyfill support
The module automatically loads the Intl.Locale.getWeekInfo() polyfill only when needed (e.g. in Node or older
environments). But you can import it explicitly too:
import "temporal-extra/week-info/polyfill";NOTE: This also automatically augments the global TypeScript types for
Intl.Locale.prototype.getWeekInfo.
Now you can use the API even when your environment does not support it:
new Intl.Locale("de-DE").getWeekInfo();
// { firstDay: 1, weekend: [6, 7] }The polyfill is tiny, brotli-compressed clocking in at just a little over 400 bytes!
Development
The test suite loads temporal-polyfill/full/global only when the runtime has no native Temporal. Two quirks to be
aware of when running tests locally:
- On Node.js >= 26 the tests run against V8's native
Temporal, which currently ships an outdatedtemporal_rswith a hebrew leap-year bug:with()maps ordinal months without the leap-month offset, failing one adjuster test. This is fixed upstream (nodejs/node#63145, nodejs/node#63281) and will ship in an upcoming v26 release. c8(the coverage wrapper used bypnpm test) crashes on Node.js >= 26: its yargs 17 dependency ships an extensionless CJS file that newer Node's module-syntax detection runs as ESM (bcoe/c8#592). Runtsx --import=./test/temporal-polyfill.ts --testdirectly instead.
CI runs on Node.js 22/24, where the polyfill is always active and neither issue applies.
