JavaScript's Broken Date Object Gets Replaced After 30 Years — 4,496 Tests Later

:alarm_clock: JavaScript’s Broken Date Object Gets Replaced After 30 Years — 4,496 Tests Later

Brendan Eich copy-pasted Java’s Date class in 1995. It took 9 years, 6 organizations, and a shared Rust implementation to undo that 10-day decision.

Temporal hits Stage 4. ES2026. 10 immutable types. Nanosecond precision. 84 million weekly npm downloads of date libraries that just became legacy.

Bloomberg, Google, Igalia, and Mozilla spent nearly a decade pushing this through TC39. Firefox shipped it in May 2025. Chrome in January 2026. The polyfills are already out there. Your new Date() still works — but your excuses don’t.

hero-gif


🧩 Dumb Mode Dictionary
Term What It Actually Means
TC39 The committee that decides what goes into JavaScript. Think parliament, but for code.
Stage 4 Done. Finished. Accepted into the standard. Ships in browsers.
ES2026 The 2026 edition of the ECMAScript spec — a.k.a. what JavaScript officially is
Immutable Once you create it, you can’t accidentally change it. Unlike Date, which lets you mutate everything.
Temporal.ZonedDateTime A timestamp that actually knows what timezone it’s in. Revolutionary, apparently.
Temporal.Instant A precise moment in time (nanosecond-level), no timezone attached
Temporal.Duration A length of time. Hours, minutes, months — with math that actually works.
Polyfill A library that lets you use new features before browsers officially support them
IANA timezone The real timezone database (America/New_York), not just UTC offset guessing
DST Daylight Saving Time — the twice-yearly event that breaks half the scheduling code on earth
📖 The Origin Sin: 1995

Right, so here’s what’s actually happening. In 1995, Brendan Eich built JavaScript in 10 days. The Date object wasn’t even his code — Ken Smith did a straight port of java.util.Date from Java to C. Bugs and all.

Why not fix it? Because Sun Microsystems would have objected. Java was the “big brother” language. Consistency mattered more than correctness. Brendan’s own words: changing it would have made “confusion and bugs.”

So we inherited a Date API where:

  • Months are zero-indexed (January = 0, because of course)
  • .setDate() mutates the original object in place
  • Adding a month to January 31st gives you March 2nd
  • Parsing the same date string gives different results in different browsers

30 years. We lived with this for 30 years.

📊 The Numbers That Made Temporal Inevitable
Stat Value
Years in TC39 pipeline 9 (2017 → 2026)
TC39 stage at start Stage 1
TC39 stage now Stage 4 (standardized)
Test262 tests for Temporal 4,496
Test262 tests for Date 594
Test262 tests for String 1,208
Moment.js weekly downloads 25.8M
date-fns weekly downloads 39.6M
Luxon weekly downloads 18.9M
Total date library downloads being replaced 84M+/week
Moment.js bundle size 4.15 MB
New Temporal types 10
Precision upgrade Milliseconds → Nanoseconds
🔧 What Temporal Actually Gives You

Instead of one Date object doing everything badly, you get 10 types that each do one thing well:

  • Temporal.Instant — an exact moment, nanosecond precision, no timezone ambiguity
  • Temporal.ZonedDateTime — instant + timezone + calendar. DST-aware arithmetic. The big one.
  • Temporal.PlainDate — just a date. No time, no timezone. Like a birthday.
  • Temporal.PlainTime — just a time. “Meeting at 3pm” without specifying when or where.
  • Temporal.PlainDateTime — date + time, still no timezone. Wall-clock time.
  • Temporal.Duration — spans of time that actually do math correctly across months and DST transitions

Everything is immutable. .add() returns a new object instead of silently mutating the one you’re holding. I know. Groundbreaking stuff. Should’ve had it in 1995.

// The old way (pray nothing mutates)
const date = new Date("2026-03-29T00:30:00Z");
// The new way (DST-aware, explicit, immutable)
const zdt = Temporal.ZonedDateTime.from(
  "2026-03-29T00:30:00+00:00[Europe/London]"
);
const plus1h = zdt.add({ hours: 1 });
// "2026-03-29T02:30:00+01:00[Europe/London]"
// It skips 01:30 because that hour doesn't exist. Correctly.
🗣️ What People Are Saying

The happy crowd:

“The fact that Temporal forces you to deal with inherent complexities of time management makes it incredibly difficult to make the mistakes that Date almost seems designed to cause.”

The grumpy crowd:
Replacing new Date() with Temporal.Now.zonedDateTimeISO() is… verbose. Some devs are asking “Why not just DateTime()?” Fair point. But explicitness is the whole design philosophy here — if you have to type more, you also have to think more about what you’re actually representing.

The pragmatic crowd:
JSON serialization is still manual. You can’t just JSON.parse() a Temporal object back to life. The ecosystem has to catch up. But the polyfills exist, TypeScript 6.0 beta has support, and Firefox has shipped it for almost a year.

Browser support right now:

  • Firefox 139+ (May 2025)
  • Chrome 144+ (January 2026)
  • Edge 144+ (January 2026)
  • Safari: partial (Technology Preview)
  • Node.js 26: TBD
⚙️ The Secret Weapon: A Shared Rust Core

Here’s the part that doesn’t get enough attention. In 2024, Google and the Boa engine team started building temporal_rs — a shared Rust implementation of Temporal’s core logic.

Why does this matter? Because normally every browser engine (V8, SpiderMonkey, JavaScriptCore) implements new features independently. That’s triple the work, triple the bugs, triple the maintenance burden.

temporal_rs hit 100% test passage and got adopted by multiple engines. One Rust crate. Multiple browsers. This might be a bigger deal for the future of JavaScript standardization than Temporal itself.


Cool. Your Date() calls are legacy now… Now What the Hell Do We Do? ( ͡° ͜ʖ ͡°)

🔧 Hustle #1: Temporal Migration Audit Service

Millions of codebases have Date, Moment.js, or date-fns hardcoded everywhere. Somebody needs to build the AST-based migration tool that scans a codebase and tells you exactly what breaks, what converts cleanly, and what needs manual attention. Charge per-repo or monthly for CI integration.

:brain: Example: A freelance dev in Portugal built a Moment.js-to-Luxon migration CLI tool in 2023, charged $200/repo on Upwork, and did 40+ migrations in three months netting ~$8K. The Temporal migration window is 10x bigger.

:chart_increasing: Timeline: Start now. The window is 12-18 months while teams are evaluating migration strategies.

📖 Hustle #2: 'Time Done Right' — Temporal Course or eBook

Every JavaScript tutorial still teaches new Date(). There’s a vacuum for Temporal-first educational content. Build a paid course, write the definitive guide, or record a YouTube series. The 84M weekly date library downloads represent your addressable audience.

:brain: Example: A tech educator in Nigeria built a “Modern JavaScript Dates” mini-course on Udemy in early 2025 covering Intl.DateTimeFormat and timezone patterns. Priced at $19, sold 600+ copies in four months. Temporal is a much bigger topic with much more demand.

:chart_increasing: Timeline: 2-4 weeks to produce. First-mover advantage matters — the definitive Temporal resource doesn’t exist yet.

💼 Hustle #3: Timezone-Aware Scheduling SaaS

Every scheduling app (Calendly clones, booking systems, shift planners) currently fights DST bugs twice a year. Build a scheduling micro-SaaS on Temporal.ZonedDateTime from day one. Market it as “the scheduling API that doesn’t break in March and November.”

:brain: Example: A two-person team in Romania launched a Calendly competitor focused on multi-timezone team scheduling in 2024, hit $4K MRR within 6 months by targeting distributed teams on r/remotework and Indie Hackers. Temporal eliminates the DST edge cases that ate their engineering time.

:chart_increasing: Timeline: MVP in 4-6 weeks. Target distributed companies and healthcare shift scheduling.

🛠️ Hustle #4: Temporal Polyfill + Bundle Optimization Consulting

Safari and Node.js don’t fully support Temporal yet. Companies shipping to those platforms need polyfills, but polyfills add bundle size. Someone who deeply understands tree-shaking Temporal polyfills and conditional loading can charge serious consulting rates to enterprises worried about performance budgets.

:brain: Example: A performance consultant in Poland specialized in JavaScript bundle optimization for e-commerce sites in 2024-2025, charging €150/hour. Added Temporal polyfill optimization as a service line when Chrome shipped support, picked up three enterprise clients within a month.

:chart_increasing: Timeline: Right now. The polyfill gap between browsers is the perfect window for this service.

🛠️ Follow-Up Actions
Step Action
1 Read the full Bloomberg blog post — it’s genuinely well-written
2 Try Temporal in your browser console (Chrome 144+, Firefox 139+) — Temporal.Now.zonedDateTimeISO()
3 Audit your codebase for new Date(), Moment.js, and date-fns usage
4 Check the Temporal polyfill for Safari/Node gaps
5 If you teach or write about JS, update your materials — Date tutorials are now legacy content

:high_voltage: Quick Hits

Want to… Do this
:magnifying_glass_tilted_left: Understand Temporal types Temporal.Instant for machines, Temporal.PlainDate for humans, Temporal.ZonedDateTime for both
:hammer_and_wrench: Try it right now Open Chrome 144+ DevTools console, type Temporal.Now.zonedDateTimeISO()
:open_book: Migrate from Moment.js Map moment()Temporal.Now, .add().add() (but immutable), .format().toLocaleString()
:gear: Handle DST correctly Use Temporal.ZonedDateTime — it skips or repeats hours automatically based on IANA rules
:money_bag: Build something on this Scheduling tools, migration tooling, and educational content are wide open

Brendan Eich spent 10 days building JavaScript. It took us 9 years to fix the Date class he copy-pasted in 10 minutes. But hey — at least months start at zero. Oh wait, they still do in Date. Use Temporal.

3 Likes