A lightweight polyfill for Temporal, successor to the JavaScript Date object
npx @tessl/cli install tessl/npm-temporal-polyfill@0.3.0Temporal Polyfill provides a lightweight polyfill implementation of the Temporal API, which is the successor to JavaScript's Date object. The polyfill is designed to be highly optimized with only 20 KB minified+gzipped size, making it significantly smaller than alternative implementations while maintaining near-perfect spec compliance with just 4 intentional deviations.
npm install temporal-polyfillStandard import for ES modules:
import { Temporal, Intl } from "temporal-polyfill";Implementation-only import:
import { Temporal, Intl, toTemporalInstant } from "temporal-polyfill/impl";Global polyfill (adds to globalThis):
import "temporal-polyfill/global";
// Now Temporal and enhanced Intl are available globallyFor CommonJS:
const { Temporal, Intl } = require("temporal-polyfill");import { Temporal } from "temporal-polyfill";
// Current time
const now = Temporal.Now.instant();
const today = Temporal.Now.plainDateISO();
// Create specific dates and times
const date = Temporal.PlainDate.from("2024-03-15");
const time = Temporal.PlainTime.from("14:30:00");
const dateTime = Temporal.PlainDateTime.from("2024-03-15T14:30:00");
// With timezone
const zonedDateTime = Temporal.ZonedDateTime.from("2024-03-15T14:30:00[America/New_York]");
// Durations
const duration = Temporal.Duration.from({ hours: 2, minutes: 30 });
const futureDate = date.add(duration);
// Formatting with enhanced Intl
const formatter = new Intl.DateTimeFormat("en-US", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric"
});
console.log(formatter.format(date));Temporal Polyfill is organized around several key components:
Core classes for representing dates, times, and moments with comprehensive functionality for manipulation and formatting.
// Basic date/time classes
class PlainDate {
static from(item: PlainDateLike | string, options?: AssignmentOptions): PlainDate;
static compare(one: PlainDateLike, two: PlainDateLike): ComparisonResult;
constructor(isoYear: number, isoMonth: number, isoDay: number, calendar?: CalendarLike);
readonly year: number;
readonly month: number;
readonly day: number;
add(duration: DurationLike, options?: ArithmeticOptions): PlainDate;
subtract(duration: DurationLike, options?: ArithmeticOptions): PlainDate;
with(dateLike: PlainDateLike, options?: AssignmentOptions): PlainDate;
until(other: PlainDateLike, options?: DifferenceOptions<DateUnit>): Duration;
since(other: PlainDateLike, options?: DifferenceOptions<DateUnit>): Duration;
equals(other: PlainDateLike): boolean;
toString(options?: ShowCalendarOption): string;
}
class PlainTime {
static from(item: PlainTimeLike | string, options?: AssignmentOptions): PlainTime;
static compare(one: PlainTimeLike, two: PlainTimeLike): ComparisonResult;
constructor(hour?: number, minute?: number, second?: number, millisecond?: number, microsecond?: number, nanosecond?: number);
readonly hour: number;
readonly minute: number;
readonly second: number;
readonly millisecond: number;
readonly microsecond: number;
readonly nanosecond: number;
add(duration: DurationLike): PlainTime;
subtract(duration: DurationLike): PlainTime;
with(timeLike: PlainTimeLike, options?: AssignmentOptions): PlainTime;
until(other: PlainTimeLike, options?: DifferenceOptions<TimeUnit>): Duration;
since(other: PlainTimeLike, options?: DifferenceOptions<TimeUnit>): Duration;
round(roundTo: TimeUnit | RoundingOptions<TimeUnit>): PlainTime;
equals(other: PlainTimeLike): boolean;
toString(options?: ToStringPrecisionOptions): string;
}
class PlainDateTime {
static from(item: PlainDateTimeLike | string, options?: AssignmentOptions): PlainDateTime;
static compare(one: PlainDateTimeLike, two: PlainDateTimeLike): ComparisonResult;
constructor(isoYear: number, isoMonth: number, isoDay: number, hour?: number, minute?: number, second?: number, millisecond?: number, microsecond?: number, nanosecond?: number, calendar?: CalendarLike);
// All PlainDate and PlainTime properties
readonly year: number;
readonly month: number;
readonly day: number;
readonly hour: number;
readonly minute: number;
readonly second: number;
readonly millisecond: number;
readonly microsecond: number;
readonly nanosecond: number;
add(duration: DurationLike, options?: ArithmeticOptions): PlainDateTime;
subtract(duration: DurationLike, options?: ArithmeticOptions): PlainDateTime;
with(dateTimeLike: PlainDateTimeLike, options?: AssignmentOptions): PlainDateTime;
withPlainTime(plainTime?: PlainTimeLike): PlainDateTime;
round(roundTo: DateTimeUnit | RoundingOptions<DateTimeUnit>): PlainDateTime;
equals(other: PlainDateTimeLike): boolean;
toString(options?: CalendarDisplayOptions & ToStringPrecisionOptions): string;
}Classes for representing exact moments in time and timezone-aware date-times with full timezone support.
class Instant {
static from(item: InstantLike | string): Instant;
static fromEpochMilliseconds(epochMilliseconds: number): Instant;
static fromEpochNanoseconds(epochNanoseconds: bigint): Instant;
static compare(one: InstantLike, two: InstantLike): ComparisonResult;
readonly epochMilliseconds: number;
readonly epochNanoseconds: bigint;
add(duration: DurationLike): Instant;
subtract(duration: DurationLike): Instant;
until(other: InstantLike, options?: DifferenceOptions<TimeUnit>): Duration;
since(other: InstantLike, options?: DifferenceOptions<TimeUnit>): Duration;
round(roundTo: TimeUnit | RoundingOptions<TimeUnit>): Instant;
equals(other: InstantLike): boolean;
toZonedDateTimeISO(timeZone: TimeZoneLike): ZonedDateTime;
toString(options?: InstantToStringOptions): string;
}
class ZonedDateTime {
static from(item: ZonedDateTimeLike | string, options?: ZonedDateTimeAssignmentOptions): ZonedDateTime;
static compare(one: ZonedDateTimeLike, two: ZonedDateTimeLike): ComparisonResult;
// All PlainDateTime properties plus timezone-specific ones
readonly timeZoneId: string;
readonly offset: string;
readonly offsetNanoseconds: number;
readonly epochSeconds: number;
readonly epochMilliseconds: number;
readonly epochMicroseconds: bigint;
readonly epochNanoseconds: bigint;
readonly hoursInDay: number;
readonly startOfDay: ZonedDateTime;
add(duration: DurationLike, options?: ArithmeticOptions): ZonedDateTime;
subtract(duration: DurationLike, options?: ArithmeticOptions): ZonedDateTime;
with(zonedDateTimeLike: ZonedDateTimeLike, options?: ZonedDateTimeAssignmentOptions): ZonedDateTime;
withTimeZone(timeZone: TimeZoneLike): ZonedDateTime;
round(roundTo: DateTimeUnit | RoundingOptions<DateTimeUnit>): ZonedDateTime;
equals(other: ZonedDateTimeLike): boolean;
toInstant(): Instant;
toString(options?: ZonedDateTimeToStringOptions): string;
}Duration class for representing time spans and performing date arithmetic operations.
class Duration {
static from(item: DurationLike | string): Duration;
static compare(one: DurationLike, two: DurationLike, options?: DurationArithmeticOptions): ComparisonResult;
constructor(years?: number, months?: number, weeks?: number, days?: number, hours?: number, minutes?: number, seconds?: number, milliseconds?: number, microseconds?: number, nanoseconds?: number);
readonly years: number;
readonly months: number;
readonly weeks: number;
readonly days: number;
readonly hours: number;
readonly minutes: number;
readonly seconds: number;
readonly milliseconds: number;
readonly microseconds: number;
readonly nanoseconds: number;
readonly sign: -1 | 0 | 1;
readonly blank: boolean;
with(durationLike: DurationLike): Duration;
negated(): Duration;
abs(): Duration;
add(other: DurationLike, options?: DurationArithmeticOptions): Duration;
subtract(other: DurationLike, options?: DurationArithmeticOptions): Duration;
round(roundTo: DurationUnit | DurationRoundingOptions): Duration;
total(totalOf: DurationUnit | DurationTotalOfOptions): number;
toString(options?: DurationToStringOptions): string;
}Specialized classes for working with calendar-specific date components like year-month and month-day combinations.
class PlainYearMonth {
static from(item: PlainYearMonthLike | string, options?: AssignmentOptions): PlainYearMonth;
static compare(one: PlainYearMonthLike, two: PlainYearMonthLike): ComparisonResult;
readonly year: number;
readonly month: number;
readonly monthCode: string;
readonly daysInMonth: number;
readonly daysInYear: number;
readonly monthsInYear: number;
readonly inLeapYear: boolean;
add(duration: DurationLike, options?: ArithmeticOptions): PlainYearMonth;
subtract(duration: DurationLike, options?: ArithmeticOptions): PlainYearMonth;
with(yearMonthLike: PlainYearMonthLike, options?: AssignmentOptions): PlainYearMonth;
until(other: PlainYearMonthLike, options?: DifferenceOptions<YearMonthUnit>): Duration;
since(other: PlainYearMonthLike, options?: DifferenceOptions<YearMonthUnit>): Duration;
equals(other: PlainYearMonthLike): boolean;
toPlainDate(day: PlainDateLike): PlainDate;
toString(options?: ShowCalendarOption): string;
}
class PlainMonthDay {
static from(item: PlainMonthDayLike | string, options?: AssignmentOptions): PlainMonthDay;
readonly monthCode: string;
readonly day: number;
with(monthDayLike: PlainMonthDayLike, options?: AssignmentOptions): PlainMonthDay;
equals(other: PlainMonthDayLike): boolean;
toPlainDate(year: PlainYearMonthLike): PlainDate;
toString(options?: ShowCalendarOption): string;
}Utilities for getting current time values in various Temporal formats and time zones.
namespace Now {
function timeZoneId(): string;
function instant(): Instant;
function plainDateTimeISO(timeZone?: TimeZoneLike): PlainDateTime;
function zonedDateTimeISO(timeZone?: TimeZoneLike): ZonedDateTime;
function plainDateISO(timeZone?: TimeZoneLike): PlainDate;
function plainTimeISO(timeZone?: TimeZoneLike): PlainTime;
}Enhanced Intl.DateTimeFormat with native Temporal type support for formatting dates and times.
class DateTimeFormat extends Intl.DateTimeFormat {
constructor(locales?: LocalesArgument, options?: Intl.DateTimeFormatOptions);
format(date: TemporalObject | Date): string;
formatToParts(date: TemporalObject | Date): Intl.DateTimeFormatPart[];
formatRange(startDate: TemporalObject, endDate: TemporalObject): string;
formatRangeToParts(startDate: TemporalObject, endDate: TemporalObject): Intl.DateTimeFormatPart[];
}
interface TemporalObject {
// Union of all formattable Temporal types
}// Core argument types
type PlainDateLike = PlainDate | PlainDateISOFields;
type PlainTimeLike = PlainTime | PlainTimeISOFields;
type PlainDateTimeLike = PlainDateTime | PlainDateTimeISOFields;
type ZonedDateTimeLike = ZonedDateTime | ZonedDateTimeISOFields | string;
type DurationLike = Duration | DurationFields | string;
type InstantLike = Instant | string;
type CalendarLike = string | Calendar;
type TimeZoneLike = string | TimeZone;
// Field interfaces
interface PlainDateISOFields {
era?: string;
eraYear?: number;
year: number;
month: number;
monthCode?: string;
day: number;
calendar?: CalendarLike;
}
interface PlainTimeISOFields {
hour?: number;
minute?: number;
second?: number;
millisecond?: number;
microsecond?: number;
nanosecond?: number;
}
interface PlainDateTimeISOFields extends PlainDateISOFields, PlainTimeISOFields {}
interface ZonedDateTimeISOFields extends PlainDateTimeISOFields {
timeZone: TimeZoneLike;
offset?: string;
}
interface DurationFields {
years?: number;
months?: number;
weeks?: number;
days?: number;
hours?: number;
minutes?: number;
seconds?: number;
milliseconds?: number;
microseconds?: number;
nanoseconds?: number;
}
// Units and options
type DateUnit = 'year' | 'month' | 'week' | 'day';
type TimeUnit = 'hour' | 'minute' | 'second' | 'millisecond' | 'microsecond' | 'nanosecond';
type DateTimeUnit = DateUnit | TimeUnit;
type DurationUnit = DateTimeUnit;
type YearMonthUnit = 'year' | 'month';
type ComparisonResult = -1 | 0 | 1;
type RoundingMode = 'ceil' | 'floor' | 'expand' | 'trunc' | 'halfCeil' | 'halfFloor' | 'halfExpand' | 'halfTrunc' | 'halfEven';
type OverflowMode = 'constrain' | 'reject';
type DisambiguationMode = 'compatible' | 'earlier' | 'later' | 'reject';
type OffsetDisambiguationMode = 'use' | 'ignore' | 'prefer' | 'reject';
// Option interfaces
interface AssignmentOptions {
overflow?: OverflowMode;
}
interface ArithmeticOptions {
overflow?: OverflowMode;
}
interface DifferenceOptions<T extends string> {
largestUnit?: T;
smallestUnit?: T;
roundingIncrement?: number;
roundingMode?: RoundingMode;
}
interface RoundingOptions<T extends string> {
smallestUnit: T;
roundingIncrement?: number;
roundingMode?: RoundingMode;
}
interface ZonedDateTimeAssignmentOptions extends AssignmentOptions {
disambiguation?: DisambiguationMode;
offset?: OffsetDisambiguationMode;
}
interface DurationArithmeticOptions {
relativeTo?: PlainDateLike | ZonedDateTimeLike | string;
}