A lightweight polyfill for Temporal, successor to the JavaScript Date object
Overall
score
96%
Evaluation — 96%
↑ 1.19xAgent success when using this tile
Classes for representing exact moments in time and timezone-aware date-times. These classes provide precise time handling with full timezone support and epoch-based calculations.
Represents a single moment in time measured from the Unix epoch. Ideal for timestamps, logging, and any application requiring precise time measurements.
/**
* Represents a single moment in time (Unix timestamp)
*/
class Instant {
/** Creates an Instant from various inputs */
static from(item: InstantLike | string): Instant;
/** Creates an Instant from epoch milliseconds */
static fromEpochMilliseconds(epochMilliseconds: number): Instant;
/** Creates an Instant from epoch nanoseconds */
static fromEpochNanoseconds(epochNanoseconds: bigint): Instant;
/** Compares two instants and returns -1, 0, or 1 */
static compare(one: InstantLike, two: InstantLike): ComparisonResult;
// Epoch time properties
readonly epochMilliseconds: number;
readonly epochNanoseconds: bigint;
// Time manipulation methods
/** Returns a new Instant with the duration added */
add(duration: DurationLike): Instant;
/** Returns a new Instant with the duration subtracted */
subtract(duration: DurationLike): Instant;
// Comparison and difference methods
/** Returns the duration from this instant until the other instant */
until(other: InstantLike, options?: DifferenceOptions<TimeUnit>): Duration;
/** Returns the duration from the other instant since this instant */
since(other: InstantLike, options?: DifferenceOptions<TimeUnit>): Duration;
/** Rounds this instant to the specified unit or precision */
round(roundTo: TimeUnit | RoundingOptions<TimeUnit>): Instant;
/** Tests if this instant equals another instant */
equals(other: InstantLike): boolean;
// Conversion methods
/** Converts this instant to a ZonedDateTime in the specified timezone */
toZonedDateTimeISO(timeZone: TimeZoneLike): ZonedDateTime;
// String representation methods
/** Returns a locale-formatted string representation */
toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;
/** Returns an ISO 8601 string representation */
toString(options?: InstantToStringOptions): string;
/** Returns a JSON representation (same as toString) */
toJSON(): string;
/** Throws a TypeError when used in comparison operators */
valueOf(): never;
}Usage Examples:
import { Temporal } from "temporal-polyfill";
// Creating instants
const now = Temporal.Now.instant();
const fromEpoch = Temporal.Instant.fromEpochMilliseconds(1640995200000);
const fromString = Temporal.Instant.from("2022-01-01T00:00:00Z");
// Converting from Date
const legacyDate = new Date();
const instant = legacyDate.toTemporalInstant();
// Time calculations
const oneHourLater = now.add({ hours: 1 });
const tenMinutesAgo = now.subtract({ minutes: 10 });
// Measuring time differences
const startTime = Temporal.Now.instant();
// ... do some work ...
const endTime = Temporal.Now.instant();
const elapsed = startTime.until(endTime, { smallestUnit: 'millisecond' });
// Rounding for precision
const roundedToSecond = now.round('second');
const roundedToMinute = now.round({ smallestUnit: 'minute', roundingMode: 'floor' });
// Timezone conversions
const inUtc = now.toZonedDateTimeISO('UTC');
const inNewYork = now.toZonedDateTimeISO('America/New_York');
const inTokyo = now.toZonedDateTimeISO('Asia/Tokyo');
// Comparisons
const isLater = Temporal.Instant.compare(oneHourLater, now) > 0;
const timeDiff = now.until(oneHourLater).total('minutes'); // 60Represents a date and time with timezone information. Combines all PlainDateTime functionality with timezone handling, DST awareness, and offset calculations.
/**
* Represents a date and time with timezone information
*/
class ZonedDateTime {
/** Creates a ZonedDateTime from various inputs */
static from(item: ZonedDateTimeLike | string, options?: ZonedDateTimeAssignmentOptions): ZonedDateTime;
/** Compares two zoned date-times and returns -1, 0, or 1 */
static compare(one: ZonedDateTimeLike, two: ZonedDateTimeLike): ComparisonResult;
// All PlainDateTime properties
readonly calendarId: string;
readonly year: number;
readonly month: number;
readonly monthCode: string;
readonly day: number;
readonly hour: number;
readonly minute: number;
readonly second: number;
readonly millisecond: number;
readonly microsecond: number;
readonly nanosecond: number;
readonly era: string | undefined;
readonly eraYear: number | undefined;
readonly dayOfWeek: number;
readonly dayOfYear: number;
readonly weekOfYear: number;
readonly yearOfWeek: number;
readonly daysInWeek: number;
readonly daysInMonth: number;
readonly daysInYear: number;
readonly monthsInYear: number;
readonly inLeapYear: boolean;
// Timezone-specific properties
readonly timeZoneId: string;
readonly offset: string;
readonly offsetNanoseconds: number;
readonly epochMilliseconds: number;
readonly epochNanoseconds: bigint;
// Timezone-aware computed properties
readonly hoursInDay: number;
readonly startOfDay: ZonedDateTime;
// DateTime manipulation methods (timezone-aware)
/** Returns a new ZonedDateTime with the duration added */
add(duration: DurationLike, options?: ArithmeticOptions): ZonedDateTime;
/** Returns a new ZonedDateTime with the duration subtracted */
subtract(duration: DurationLike, options?: ArithmeticOptions): ZonedDateTime;
/** Returns a new ZonedDateTime with the specified fields changed */
with(zonedDateTimeLike: ZonedDateTimeLike, options?: ZonedDateTimeAssignmentOptions): ZonedDateTime;
/** Changes the calendar system of this zoned date-time */
withCalendar(calendar: CalendarLike): ZonedDateTime;
/** Changes the timezone of this zoned date-time */
withTimeZone(timeZone: TimeZoneLike): ZonedDateTime;
/** Changes the time portion of this zoned date-time */
withPlainTime(plainTime?: PlainTimeLike): ZonedDateTime;
// Comparison and difference methods
/** Returns the duration from this zoned date-time until the other zoned date-time */
until(other: ZonedDateTimeLike, options?: DifferenceOptions<DateTimeUnit>): Duration;
/** Returns the duration from the other zoned date-time since this zoned date-time */
since(other: ZonedDateTimeLike, options?: DifferenceOptions<DateTimeUnit>): Duration;
/** Rounds this zoned date-time to the specified unit or precision */
round(roundTo: DateTimeUnit | RoundingOptions<DateTimeUnit>): ZonedDateTime;
/** Tests if this zoned date-time equals another zoned date-time */
equals(other: ZonedDateTimeLike): boolean;
// Conversion methods
/** Converts this zoned date-time to an Instant */
toInstant(): Instant;
/** Converts this zoned date-time to a PlainDateTime (loses timezone) */
toPlainDateTime(): PlainDateTime;
/** Extracts the date portion */
toPlainDate(): PlainDate;
/** Extracts the time portion */
toPlainTime(): PlainTime;
/** Extracts the year-month portion */
toPlainYearMonth(): PlainYearMonth;
/** Extracts the month-day portion */
toPlainMonthDay(): PlainMonthDay;
/** Gets the TimeZone object for this zoned date-time */
getTimeZone(): TimeZone;
// String representation methods
/** Returns a locale-formatted string representation */
toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;
/** Returns an ISO 8601 string representation with timezone */
toString(options?: ZonedDateTimeToStringOptions): string;
/** Returns a JSON representation (same as toString) */
toJSON(): string;
/** Throws a TypeError when used in comparison operators */
valueOf(): never;
}Usage Examples:
import { Temporal } from "temporal-polyfill";
// Creating zoned date-times
const nowInNewYork = Temporal.Now.zonedDateTimeISO('America/New_York');
const fromString = Temporal.ZonedDateTime.from('2024-03-15T14:30:00-04:00[America/New_York]');
const fromObject = Temporal.ZonedDateTime.from({
year: 2024,
month: 3,
day: 15,
hour: 14,
minute: 30,
timeZone: 'America/New_York'
});
// From PlainDateTime
const plainDT = Temporal.PlainDateTime.from('2024-03-15T14:30:00');
const zonedDT = plainDT.toZonedDateTime('America/New_York');
// Timezone conversions
const inLondon = nowInNewYork.withTimeZone('Europe/London');
const inTokyo = nowInNewYork.withTimeZone('Asia/Tokyo');
// DST-aware arithmetic
const springForward = Temporal.ZonedDateTime.from('2024-03-10T01:30:00-05:00[America/New_York]');
const afterDST = springForward.add({ hours: 2 }); // Handles DST transition
console.log(springForward.hoursInDay); // 23 hours (spring forward day)
// Working with business hours
const businessDay = Temporal.ZonedDateTime.from('2024-03-15T09:00:00[America/New_York]');
const endOfDay = businessDay.with({ hour: 17, minute: 0 });
const workingHours = businessDay.until(endOfDay, { largestUnit: 'hour' });
// Handling ambiguous times (DST transitions)
const ambiguousTime = Temporal.ZonedDateTime.from(
'2024-11-03T01:30:00[America/New_York]',
{ disambiguation: 'earlier' } // Choose first occurrence
);
// Time zone offset information
console.log(nowInNewYork.offset); // e.g., "-05:00" or "-04:00"
console.log(nowInNewYork.offsetNanoseconds); // Offset in nanoseconds
// Start of day in timezone (handles DST)
const startOfDay = nowInNewYork.startOfDay;
const midnight = nowInNewYork.with({ hour: 0, minute: 0, second: 0 });
// Conversions
const instant = nowInNewYork.toInstant();
const plainDateTime = nowInNewYork.toPlainDateTime();
const justDate = nowInNewYork.toPlainDate();
// Comparisons across timezones
const nyTime = Temporal.ZonedDateTime.from('2024-01-01T12:00:00[America/New_York]');
const londonTime = Temporal.ZonedDateTime.from('2024-01-01T17:00:00[Europe/London]');
const areEqual = nyTime.equals(londonTime); // true - same instantExtension to the native Date object for converting to Temporal types.
/**
* Extension to Date.prototype for Temporal integration
*/
interface Date {
/** Converts a legacy Date to a Temporal.Instant */
toTemporalInstant(): Instant;
}Usage Examples:
// Converting legacy dates
const legacyDate = new Date();
const instant = legacyDate.toTemporalInstant();
const zonedDateTime = instant.toZonedDateTimeISO(Temporal.Now.timeZoneId());
// Migration pattern
function modernizeTimestamp(legacyTimestamp: Date): Temporal.ZonedDateTime {
return legacyTimestamp
.toTemporalInstant()
.toZonedDateTimeISO('UTC');
}// Core type definitions for instants and zoned date-times
type InstantLike = Instant | string;
type ZonedDateTimeLike = ZonedDateTime | ZonedDateTimeFields | string;
type TimeZoneLike = string | TimeZone;
interface ZonedDateTimeFields {
era?: string;
eraYear?: number;
year: number;
month?: number;
monthCode?: string;
day: number;
hour?: number;
minute?: number;
second?: number;
millisecond?: number;
microsecond?: number;
nanosecond?: number;
timeZone: TimeZoneLike;
offset?: string;
calendar?: CalendarLike;
}
// Timezone-specific options
type DisambiguationMode = 'compatible' | 'earlier' | 'later' | 'reject';
type OffsetDisambiguationMode = 'use' | 'ignore' | 'prefer' | 'reject';
interface ZonedDateTimeAssignmentOptions extends AssignmentOptions {
disambiguation?: DisambiguationMode;
offset?: OffsetDisambiguationMode;
}
// String formatting options
interface InstantToStringOptions {
timeZone?: TimeZoneLike;
fractionalSecondDigits?: 'auto' | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
smallestUnit?: TimeUnit;
roundingMode?: RoundingMode;
}
interface ZonedDateTimeToStringOptions {
fractionalSecondDigits?: 'auto' | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
smallestUnit?: DateTimeUnit;
roundingMode?: RoundingMode;
timeZoneName?: 'auto' | 'never' | 'critical';
offset?: 'auto' | 'never';
calendarName?: 'auto' | 'always' | 'never' | 'critical';
}
// TimeZone interface (for reference)
interface TimeZone {
readonly id: string;
getOffsetNanosecondsFor(instant: Instant): number;
getOffsetStringFor(instant: Instant): string;
getPlainDateTimeFor(instant: Instant, calendar?: CalendarLike): PlainDateTime;
getInstantFor(dateTime: PlainDateTime, options?: ToInstantOptions): Instant;
getPossibleInstantsFor(dateTime: PlainDateTime): Instant[];
getNextTransition(startingPoint: Instant): Instant | null;
getPreviousTransition(startingPoint: Instant): Instant | null;
toString(): string;
toJSON(): string;
}
interface ToInstantOptions {
disambiguation?: DisambiguationMode;
}Install with Tessl CLI
npx tessl i tessl/npm-temporal-polyfilldocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10