Back to blog

ES2026 Temporal API: JavaScript Finally Solves the Date Problem After 25 Years

Hello HaWkers, after more than 25 years, JavaScript will finally have a decent date API. The Temporal API is confirmed for ES2026 and promises to end all the headaches we know from the Date object. No more external libraries for basic date operations.

How many times have you needed to install moment.js, date-fns, or dayjs just to format a date or calculate the difference between two days? Those days are numbered.

The Problem with Date in JavaScript

The JavaScript Date object is notoriously problematic. It was copied from Java 1.0 in 1995 and carries all the problems from that era:

Classic Date Problems

Mutability:

// Date is mutable - this is a problem
const date = new Date('2026-01-04');
date.setMonth(5); // Modifies the original object!
console.log(date); // Jun 04 2026 - surprise!

Months start at 0:

// January is 0, December is 11 - confusing!
const january = new Date(2026, 0, 1); // January
const december = new Date(2026, 11, 25); // December

// Who has not made this mistake?
const commonError = new Date(2026, 1, 1); // February, not January!

Inconsistent timezone:

// Unpredictable behavior with timezones
const date = new Date('2026-01-04');
console.log(date.getDate()); // May return 3 or 4 depending on timezone!

Meet the Temporal API

The Temporal API solves all these problems with a modern, well-thought-out approach.

Main Types

Temporal introduces several specialized types:

// Temporal.PlainDate - date only, no time or timezone
const birthday = Temporal.PlainDate.from('2026-03-15');

// Temporal.PlainTime - time only, no date or timezone
const meeting = Temporal.PlainTime.from('14:30:00');

// Temporal.PlainDateTime - date + time, no timezone
const event = Temporal.PlainDateTime.from('2026-03-15T14:30:00');

// Temporal.ZonedDateTime - date + time + timezone (most complete)
const flight = Temporal.ZonedDateTime.from('2026-03-15T14:30:00[America/New_York]');

// Temporal.Instant - exact moment in time (like Unix timestamp)
const now = Temporal.Now.instant();

// Temporal.Duration - time duration
const duration = Temporal.Duration.from({ hours: 2, minutes: 30 });

Guaranteed Immutability

All Temporal objects are immutable:

const today = Temporal.PlainDate.from('2026-01-04');

// Operations return NEW objects
const tomorrow = today.add({ days: 1 });
const yesterday = today.subtract({ days: 1 });

console.log(today.toString());     // 2026-01-04 (unchanged!)
console.log(tomorrow.toString());  // 2026-01-05
console.log(yesterday.toString()); // 2026-01-03

Practical Operations with Temporal

Calculating Differences Between Dates

const start = Temporal.PlainDate.from('2026-01-04');
const end = Temporal.PlainDate.from('2026-03-15');

// Calculate difference
const difference = start.until(end);
console.log(difference.toString()); // P2M11D (2 months and 11 days)

// Specify desired units
const daysUntil = start.until(end, { largestUnit: 'day' });
console.log(daysUntil.days); // 70

Working with Timezones

// Convert between timezones
const meetingNY = Temporal.ZonedDateTime.from(
  '2026-03-15T09:00:00[America/New_York]'
);

const meetingLondon = meetingNY.withTimeZone('Europe/London');
console.log(meetingLondon.toString());
// 2026-03-15T13:00:00+00:00[Europe/London]

Date Formatting

const date = Temporal.PlainDate.from('2026-03-15');

const formatter = new Intl.DateTimeFormat('en-US', {
  dateStyle: 'full',
});
console.log(formatter.format(date));
// 'Sunday, March 15, 2026'

Real Use Cases

Scheduling System

interface Appointment {
  id: string;
  title: string;
  start: Temporal.ZonedDateTime;
  duration: Temporal.Duration;
}

class Scheduler {
  private appointments: Appointment[] = [];

  addAppointment(
    title: string,
    start: string,
    timezone: string,
    durationMinutes: number
  ): Appointment {
    const appointment: Appointment = {
      id: crypto.randomUUID(),
      title,
      start: Temporal.ZonedDateTime.from(`${start}[${timezone}]`),
      duration: Temporal.Duration.from({ minutes: durationMinutes }),
    };

    if (this.hasConflict(appointment)) {
      throw new Error('Time conflicts with another appointment');
    }

    this.appointments.push(appointment);
    return appointment;
  }

  hasConflict(newAppointment: Appointment): boolean {
    const newEnd = newAppointment.start.add(newAppointment.duration);

    return this.appointments.some((existing) => {
      const existingEnd = existing.start.add(existing.duration);
      return (
        Temporal.ZonedDateTime.compare(newAppointment.start, existingEnd) < 0 &&
        Temporal.ZonedDateTime.compare(newEnd, existing.start) > 0
      );
    });
  }
}

Age Calculator

function calculateAge(birthDate: string): {
  years: number;
  months: number;
  days: number;
} {
  const birth = Temporal.PlainDate.from(birthDate);
  const today = Temporal.Now.plainDateISO();

  const age = birth.until(today, { largestUnit: 'year' });

  return {
    years: age.years,
    months: age.months,
    days: age.days,
  };
}

const age = calculateAge('1990-05-15');
console.log(`${age.years} years, ${age.months} months and ${age.days} days`);

Support and Polyfills

Browser support:

  • Chrome 144+: Native support (January 2026)
  • Firefox: In development
  • Safari: In development

Using polyfill today:

npm install @js-temporal/polyfill
import { Temporal } from '@js-temporal/polyfill';

const today = Temporal.Now.plainDateISO();
console.log(today.toString());

Conclusion

The Temporal API is one of the most anticipated additions to JavaScript. After decades depending on external libraries for basic date operations, we will finally have a native, immutable, and well-designed solution.

If you work with dates in JavaScript (and who does not?), start studying the Temporal API now. Use the polyfill in new projects and prepare for when native support is widely available.

If you feel inspired by the evolution of JavaScript, I recommend checking out another article: ES Modules Dominate 2026: Why CommonJS Is Being Abandoned where you will discover another major change in the JavaScript ecosystem.

Let's go! 🦅

Comments (0)

This article has no comments yet 😢. Be the first! 🚀🦅

Add comments