惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园_首页
博客园 - 叶小钗
酷 壳 – CoolShell
酷 壳 – CoolShell
Apple Machine Learning Research
Apple Machine Learning Research
云风的 BLOG
云风的 BLOG
量子位
博客园 - 三生石上(FineUI控件)
Stack Overflow Blog
Stack Overflow Blog
小众软件
小众软件
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
V2EX
人人都是产品经理
人人都是产品经理
V
Visual Studio Blog
Jina AI
Jina AI
L
LangChain Blog
M
MIT News - Artificial intelligence
MongoDB | Blog
MongoDB | Blog
Last Week in AI
Last Week in AI
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学

MDN Blog

Introducing the MDN MCP server | MDN Blog Under the hood of MDN's new frontend | MDN Blog Image formats: Codecs and compression tools | MDN Blog A beginner-friendly guide to view transitions in CSS | MDN Blog Launching MDN's new front end | MDN Blog Image formats: Pixel data from encoders to decoders | MDN Blog Celebrating 20 years of MDN | MDN Blog Image formats: Color models for humans and devices | MDN Blog Default styles for h1 elements are changing | MDN Blog Implications of Global Privacy Control | MDN Blog Fix your website's Largest Contentful Paint by optimizing image loading | MDN Blog MDN 2024 content projects | MDN Blog A new learning experience on MDN | MDN Blog Countdown to the holidays with daily coding challenges | MDN Blog Monitoring and optimizing website performance | MDN Blog How to land your first developer job | MDN Blog Introducing the new MDN Community page | MDN Blog Fixing your website's JavaScript performance | MDN Blog Get back to school! Supercharge your learning with MDN and Scrimba | MDN Blog Efficient data handling with the Streams API | MDN Blog Locale-sensitive text segmentation in JavaScript with Intl.Segmenter | MDN Blog Optimize your workflow with Git stash | MDN Blog How to debug mobile apps across devices | MDN Blog Exclusive accordions using the HTML details element | MDN Blog Exploring the Broadcast Channel API for cross-tab communication | MDN Blog MDN partners with Scrimba to enhance web development learning | MDN Blog Introducing the MDN HTTP Observatory | MDN Blog Static Site Generation (SSG) with Next.js | MDN Blog New JavaScript Set methods | MDN Blog Securing APIs: Express rate limit and slow down | MDN Blog
JavaScript Temporal is coming | MDN Blog
Brian Smith January 24, 2025 5 minutes read · 2025-01-24 · via MDN Blog

Implementations of the new JavaScript Temporal object are starting to be shipped in experimental releases of browsers. This is big news for web developers because working with dates and times in JavaScript will be hugely simplified and modernized.

Applications that rely on scheduling, internationalization, or time-sensitive data will be able to use built-ins for efficient, precise and consistent dates, times, durations, and calendars. We're a long way away from stable, cross-browser support, and there may be changes as implementations develop, but we can already take a look at Temporal as it stands now, why it's exciting, and what problems it solves.

To help you get up to speed, there are over 270 pages of Temporal docs on MDN added this week, with detailed explanations and examples.

What is JavaScript Temporal?

To understand Temporal, we can look at JavaScript's Date object. When JavaScript was created in 1995, the Date object was copied from Java's early, flawed java.util.Date implementation. Java replaced this implementation in 1997, but JavaScript is stuck with the same API for almost 30 years, despite known problems.

The major issues with JavaScript's Date object are that it only supports the user's local time and UTC, and there's no time zone support. Additionally, its parsing behavior is very unreliable, and Date itself is mutable, which can introduce hard-to-trace bugs. There are other problems like calculations across Daylight Saving Time (DST) and historical calendar changes, which are notoriously difficult to work with.

All of these issues make working with dates and times in JavaScript complex and prone to bugs, which can have serious consequences for some systems. Most developers rely on dedicated libraries like Moment.js and date-fns for better handling of dates and times in their applications.

Temporal is designed as a full replacement for the Date object, making date and time management reliable and predictable. Temporal adds support for time zone and calendar representations, many built-in methods for conversions, comparisons and computations, formatting, and more. The API surface has over 200 utility methods, and you can find information about all of them in the Temporal docs on MDN.

Core concepts

In Temporal, the key concepts are that it has instants (unique points in history), wall-clock times (regional time), and durations. The APIs have this overall structure to handle these concepts:

  • Duration: Temporal.Duration the difference between two points in time
  • Points in time:
    • Unique points in time:
      • As a timestamp: Temporal.Instant
      • A date-time with a time zone: Temporal.ZonedDateTime
    • Time-zone-unaware date/time ("Plain"):
      • Full date and time: Temporal.PlainDateTime
        • Just the date: Temporal.PlainDate
          • Year and month: Temporal.PlainYearMonth
          • Month and day: Temporal.PlainMonthDay
        • Just the time: Temporal.PlainTime
  • Now: using Temporal.now to get the current time as various class instances, or in a specific format

Temporal examples

Some of the most basic usages of Temporal include getting current dates and times as an ISO string, but we can see from the example below, that we can now provide time zones with many methods, which takes care of complex calculations you may be doing yourself:

// The current date in the system's time zone
const dateTime = Temporal.Now.plainDateTimeISO();
console.log(dateTime); // e.g.: 2025-01-22T11:46:36.144

// The current date in the "America/New_York" time zone
const dateTimeInNewYork = Temporal.Now.plainDateTimeISO("America/New_York");
console.log(dateTimeInNewYork);
// e.g.: 2025-01-22T05:47:02.555

Working with different calendars is also simplified, as it's possible to create dates in calendar systems other than Gregorian, such as Hebrew, Chinese, and Islamic, for example. The code below helps you find out when the next Chinese New Year is (which is quite soon!):

// Chinese New Years are on 1/1 in the Chinese calendar
const chineseNewYear = Temporal.PlainMonthDay.from({
  monthCode: "M01",
  day: 1,
  calendar: "chinese",
});
const currentYear = Temporal.Now.plainDateISO().withCalendar("chinese").year;
let nextCNY = chineseNewYear.toPlainDate({ year: currentYear });
// If nextCNY is before the current date, move forward by 1 year
if (Temporal.PlainDate.compare(nextCNY, Temporal.Now.plainDateISO()) <= 0) {
  nextCNY = nextCNY.add({ years: 1 });
}
console.log(
  `The next Chinese New Year is on ${nextCNY.withCalendar("iso8601").toLocaleString()}`,
);
// The next Chinese New Year is on 1/29/2025 (at the time of writing)

Working with Unix timestamps is a very common use case as many systems (APIs, databases) use the format to represent times. The following example shows how to take a Unix Epoch timestamp in milliseconds, create an instant from it, get the current time with Temporal.Now, then calculate how many hours from now until the Unix timestamp:

// 1851222399924 is our timestamp
const launch = Temporal.Instant.fromEpochMilliseconds(1851222399924);
const now = Temporal.Now.instant();
const duration = now.until(launch, { smallestUnit: "hour" });
console.log(`It will be ${duration.toLocaleString("en-US")} until the launch`);
// "It will be 31,600 hr until the launch" <- @js-temporal/polyfill
// "It will be PT31600H until the launch" <- Firefox Nightly

Currently, toLocaleString doesn't output a locale-sensitive string in the Firefox implementation, so durations above (PT31600H) are returned as a non-locale-sensitive duration format. This may change as it's more of a design decision rather than a technical limitation as formatting the duration is possible, so the polyfill and Firefox implementations may eventually converge.

There's a lot to highlight, but one pattern that I thought was interesting in the API is the compare() methods, which allow you to sort durations in an elegant and efficient way:

const durations = [
  Temporal.Duration.from({ hours: 1 }),
  Temporal.Duration.from({ hours: 2 }),
  Temporal.Duration.from({ hours: 1, minutes: 30 }),
  Temporal.Duration.from({ hours: 1, minutes: 45 }),
];

durations.sort(Temporal.Duration.compare);
console.log(durations.map((d) => d.toString()));
// [ 'PT1H', 'PT1H30M', 'PT1H45M', 'PT2H' ]

Trying Temporal and browser support

Support is slowly starting to be included in experimental browser releases, and Firefox appears to have the most mature implementation at this point. In Firefox, Temporal is being built into the Nightly version behind the javascript.options.experimental.temporal preference. If you want to see the full compatibility story, you can check the (quite epic) Temporal object Browser Compatibility section.

Here are the main browser bugs that track Temporal implementations:

Additionally, you can visit https://tc39.es/proposal-temporal/docs/ which has @js-temporal/polyfill available. That means, you can open the developer tools on the TC39 docs page, and try some of the examples in the console in any browser without changing flags or preferences.

With experimental implementations landing, now is a good time to try out Temporal and become familiar with what will be the modern approach to handling dates and times in JavaScript.

Acknowledgements

See also