InterviewHubPRO
Section Overview
Q490

Question 490 of 521

Part 8: Modern JavaScript APIs, WeakRef, Proxy & Performance (464 - 521)

94%
JavaScript Internals (521 Qs)•Part 8: Modern JavaScript APIs, WeakRef, Proxy & Performance (464 - 521)

What is the Temporal API and why is it proposed as a replacement for Date?

The Temporal API is a modern proposal (Stage 3) to replace JavaScript's problematic Date object. It provides a better, more intuitive way to work with dates and times in JavaScript.

Problems with Date:

javascript
 // 1. Months are 0-indexed (January = 0, December = 11)
 const date1 = new Date(2024, 0, 15); // January 15, 2024 (confusing!)
 const date2 = new Date(2024, 12, 15); // Actually January 15, 2025 (overflow!)

 // 2. Mutable (can lead to bugs)
 const original = new Date('2024-01-15');
 const modified = original;
 modified.setMonth(5);
 console.log(original); // Also changed! (unexpected)

 // 3. Time zone confusion
 const date3 = new Date('2024-01-15'); // Interprets as UTC
 const date4 = new Date('2024-01-15T00:00:00'); // Interprets as local time!

 // 4. Poor API design
 date1.getYear(); // Returns 124 (not 2024!) - deprecated
 date1.getFullYear(); // Returns 2024 (correct, but confusing naming)

 // 5. No support for different calendar systems
 // Can't work with Islamic, Hebrew, Chinese calendars, etc.

 // 6. Limited date arithmetic
 // Adding months is problematic
 const jan31 = new Date(2024, 0, 31);
 jan31.setMonth(jan31.getMonth() + 1); // Feb 31 -> Mar 2 (unexpected!)

Temporal API Types:

The Temporal API provides several specialized types:

  1. Temporal.PlainDate - Date without time (e.g., birthdays, holidays)
  2. Temporal.PlainTime - Time without date (e.g., daily alarm)
  3. Temporal.PlainDateTime - Date and time without time zone
  4. Temporal.ZonedDateTime - Date, time, and time zone
  5. Temporal.Instant - Exact moment in time (like timestamps)
  6. Temporal.Duration - Length of time
  7. Temporal.PlainYearMonth - Year and month (e.g., credit card expiry)
  8. Temporal.PlainMonthDay - Month and day (e.g., recurring anniversary)

Basic Examples:

javascript
 // 1. Creating dates (intuitive month numbering!)
 const date = Temporal.PlainDate.from('2024-01-15');
 const date2 = Temporal.PlainDate.from({ year: 2024, month: 1, day: 15 });

 console.log(date.toString()); // "2024-01-15"
 console.log(date.month); // 1 (January is 1, not 0!)

 // 2. Immutable (returns new instance)
 const original = Temporal.PlainDate.from('2024-01-15');
 const modified = original.add({ months: 1 });

 console.log(original.toString()); // "2024-01-15" (unchanged)
 console.log(modified.toString()); // "2024-02-15" (new instance)

 // 3. Time zones (explicit and clear)
 const zonedDateTime = Temporal.ZonedDateTime.from({
   timeZone: 'America/New_York',
   year: 2024,
   month: 1,
   day: 15,
   hour: 10,
   minute: 30
 });

 console.log(zonedDateTime.toString());
 // "2024-01-15T10:30:00-05:00[America/New_York]"

 // Convert to different time zone
 const tokyo = zonedDateTime.withTimeZone('Asia/Tokyo');
 console.log(tokyo.toString());
 // "2024-01-16T00:30:00+09:00[Asia/Tokyo]"

 // 4. Date arithmetic (smart handling)
 const jan31 = Temporal.PlainDate.from('2024-01-31');
 const nextMonth = jan31.add({ months: 1 });
 console.log(nextMonth.toString()); // "2024-02-29" (handles leap year!)

 // Different overflow strategies
 const constrain = jan31.add({ months: 1 }, { overflow: 'constrain' });
 console.log(constrain.toString()); // "2024-02-29"

 const reject = jan31.add({ months: 1 }, { overflow: 'reject' });
 // Throws RangeError: date doesn't exist

 // 5. Duration calculations
 const start = Temporal.PlainDate.from('2024-01-15');
 const end = Temporal.PlainDate.from('2024-03-20');
 const duration = start.until(end);

 console.log(duration.toString()); // "P2M5D" (2 months, 5 days)
 console.log(duration.total({ unit: 'days' })); // 65

Real-World Use Cases:

javascript
 // 1. Birthday calculator
 function getAge(birthDate) {
   const today = Temporal.Now.plainDateISO();
   const birth = Temporal.PlainDate.from(birthDate);
   const age = birth.until(today, { largestUnit: 'years' });
   return age.years;
 }

 console.log(getAge('1990-05-15')); // Current age

 // 2. Business days calculation
 function addBusinessDays(date, days) {
   let current = Temporal.PlainDate.from(date);
   let remaining = days;

   while (remaining > 0) {
     current = current.add({ days: 1 });
     const dayOfWeek = current.dayOfWeek;
     if (dayOfWeek !== 6 && dayOfWeek !== 7) { // Not weekend
       remaining--;
     }
   }

   return current;
 }

 console.log(addBusinessDays('2024-01-15', 5).toString());

 // 3. Meeting scheduler (with time zones)
 function scheduleMeeting(localTime, attendeeTimeZones) {
   const meeting = Temporal.ZonedDateTime.from(localTime);
   
   return attendeeTimeZones.map(tz => ({
     timeZone: tz,
     time: meeting.withTimeZone(tz).toString()
   }));
 }

 const times = scheduleMeeting(
   '2024-01-15T14:00:00[America/New_York]',
   ['America/Los_Angeles', 'Europe/London', 'Asia/Tokyo']
 );

 console.log(times);
 // [
 //   { timeZone: 'America/Los_Angeles', time: '2024-01-15T11:00:00-08:00[America/Los_Angeles]' },
 //   { timeZone: 'Europe/London', time: '2024-01-15T19:00:00+00:00[Europe/London]' },
 //   { timeZone: 'Asia/Tokyo', time: '2024-01-16T04:00:00+09:00[Asia/Tokyo]' }
 // ]

 // 4. Recurring events
 function getNextOccurrence(monthDay, fromDate) {
   const target = Temporal.PlainMonthDay.from(monthDay);
   const current = Temporal.PlainDate.from(fromDate);
   
   let next = target.toPlainDate({ year: current.year });
   if (Temporal.PlainDate.compare(next, current) <= 0) {
     next = target.toPlainDate({ year: current.year + 1 });
   }
   
   return next;
 }

 console.log(getNextOccurrence('12-25', '2024-01-15').toString());
 // "2024-12-25" (next Christmas)

 // 5. Duration formatting
 function formatDuration(start, end) {
   const duration = Temporal.Instant.from(start)
     .until(Temporal.Instant.from(end));
   
   const hours = Math.floor(duration.total({ unit: 'hours' }));
   const minutes = Math.floor(duration.total({ unit: 'minutes' }) % 60);
   
   return `${hours}h ${minutes}m`;
 }

 console.log(formatDuration(
   '2024-01-15T10:00:00Z',
   '2024-01-15T13:45:00Z'
 )); // "3h 45m"

 // 6. Calendar systems
 const gregorian = Temporal.PlainDate.from('2024-01-15');
 const islamic = gregorian.withCalendar('islamic');
 const hebrew = gregorian.withCalendar('hebrew');

 console.log(gregorian.toString()); // "2024-01-15"
 console.log(islamic.toString()); // "1445-07-04[u-ca=islamic]"
 console.log(hebrew.toString()); // "5784-10-04[u-ca=hebrew]"

Comparison with Date:

javascript
 // Date (old way)
 const date = new Date();
 date.setMonth(date.getMonth() + 1); // Mutates original

 // Temporal (new way)
 const temporal = Temporal.Now.plainDateISO();
 const next = temporal.add({ months: 1 }); // Immutable

 // Time zone conversions
 // Date: Complex and error-prone
 const dateNY = new Date('2024-01-15T10:00:00');
 const dateUTC = new Date(dateNY.toISOString());
 // Messy and unreliable

 // Temporal: Clear and explicit
 const temporalNY = Temporal.ZonedDateTime.from({
   timeZone: 'America/New_York',
   year: 2024, month: 1, day: 15,
   hour: 10, minute: 0
 });
 const temporalUTC = temporalNY.withTimeZone('UTC');

Current Status and Usage:

javascript
 // As of 2026, Temporal is Stage 3 (not yet in browsers by default)
 // Use with a polyfill:
 // npm install @js-temporal/polyfill

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

 // Or use in browsers with feature detection:
 if (typeof Temporal === 'undefined') {
   // Fall back to Date or load polyfill
   console.warn('Temporal not supported, using Date');
 } else {
   // Use Temporal
   const date = Temporal.Now.plainDateISO();
 }

Benefits of Temporal:

  1. ✅ Immutable: Safer, predictable behavior
  2. ✅ Intuitive API: Months start at 1, not 0
  3. ✅ Time Zone Aware: First-class time zone support
  4. ✅ Type Safe: Different types for different use cases
  5. ✅ Calendar Support: Works with non-Gregorian calendars
  6. ✅ Better Arithmetic: Smart date calculations
  7. ✅ ISO 8601: Native support for standard date format
  8. ✅ No Legacy Baggage: Clean slate, modern design