Temporal API Duration: Working with Time Periods
Tags: webdev, javascript
Published: 2022-08-08 09:25:48

---
title: "Temporal API Duration: Working with Time Periods"
published: "true"
description: "Temporal API Duration: how you can use the new Temporal API to make working with and manipulating durations and time periods easier."
tags: "webdev, javascript"
canonical_url: "https://rodneylab.com/temporal-api-duration/"
cover_image: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kpsjcftf87o8z4jb0cbq.png"
---


## 🕚 Temporal API Duration

In this post on Temporal API duration, we see how the new JavaScript Temporal API makes working with time periods and durations easier.  The API lets you define a time period as an object in hours, minutes and seconds etc., but also using ISO 8601 notation.  ISO 8601 notation for duration crops up in a few places including Schema.org for web site SEO.  There you might use it to describe the duration of a live performance, media object or even flight time. Not to worry if you do not know what the ISO 8601 notation is, we&rsquo;ll take a look below. Even if you are not yet familiar with ISO 8601 notation, you may eventually find it a convenient way to initialise a time period.  Here to help see how you can work with duration in the Temporal API we use the track list from Madonna&rsquo;s 1980s chart topping album True Blue.

## Temporal Polyfill

The Temporal API is still a TC39 proposal and as such is not yet an official JavaScript API and not recommended for production projects.  That also means you need to use a polyfill to try it out.  This is just a package which recognises the new API&rsquo;s features and automatically translates them into code compatible with existing and established APIs.

There are a couple of APIs suggested on the TC39 site.  I tried `@js-temporal/polyfill` and have had no issues.

![Temporal API Cheatsheet: Site: screenshot show close-up on polyfill section of the site and includes details of how to install and import the polyfill for the Temporal A P I](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gjh5gjbtv02apvlnvc84.png)

## 💫 `Temporal.Duration.from()`

The API provides a few ways to initialise a Temporal Duration.  Probably, the most intuitive is:

```javascript
const duration = Temporal.Duration.from({ days: 15, hours: 7});
```

Did you spot the Sinéad O&rsquo;Connor reference in that example?  If you have a period other than seven hours and 15 days, then you have access to `years`, `months`, `weeks`, `minutes`, `seconds` and even `milliseconds`, `microseconds` and `nanoseconds`, as well as `days` and `hours`.

## 🏅 ISO 8601 Notation

For many cases ISO 8601 is more convenient.  This is just a string of letters and numbers in shorthand.  An example is `P15DT7H`.  Here `P` is just a marker that we are using an ISO 8601 period, `T` (time) separates units shorter than a day from longer units. The `15D` is fifteen days and `7H` seven hours.  The `T` separator is needed since `M` to the left of it represents months while, to the right, represents minutes.  So you can appreciate if you want to note down a period of six years, five months, four days, three hours, two minutes and one second, you can succintly write `P6Y5M4DT3H2M1S`.  There is a `W` (week) unit too, though this <a aria-label="Read T C 39 Temporal Duration docs" href="https://tc39.es/proposal-temporal/docs/duration.html">should **not** be used together with other units</a> for maximum compatibility.

Back to the previous example, we can initiate the Temporal Duration using an ISO 8601 period thus:

```javascript
const duration = Temporal.Duration.from("P15DT7H");
```

## 💿  Track List JSON Data

To see a few more Temporal duration methods, we will take a look a track list list from Madonna&rsquo;s True Blue album. If you are not into 1980s music, fear not, this is the last 1980s artist reference in this post.

```json
[
  {
    "title": "True Blue",
    "artist": "Madonna",
    "tracks": [
      { "number": 1, "title": "Papa Don’t Preach", "length": "PT4M39S" },
      { "number": 2, "title": "Open Your Heart", "length": "PT4M13S" },
      { "number": 3, "title": "White Heat", "length": "PT4M40S" },
      { "number": 4, "title": "Live to Tell", "length": "PT5M51S" },
      { "number": 5, "title": "Where’s the Party", "length": "PT4M21S" },
      { "number": 6, "title": "True Blue", "length": "PT4M18S" },
      { "number": 7, "title": "La Isla Bonita", "length": "PT4M2S" },
      { "number": 8, "title": "Jimmy Jimmy", "length": "PT3M55S" },
      { "number": 9, "title": "Love Makes the World Go Round", "length": "PT4M31S" }
    ]
  }
]
```

We will build out a quick Astro app to help illustrate the other methods.  However, don&rsquo;t worry if you don&rsquo;t know Astro; HTML and JavaScript appreciation is enough to follow along.

Here&rsquo;s our output:

![Temporal API Duration: Track Listing: screenshot shows a table of nine track with length displayed for each one and also a total length."
    caption: "Temporal API Duration: Track Listing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hmiq3y7esntnmio4jm7z.png)

Notice how in the input JSON our track lengths use ISO 8601 durations.  This is convenient as it creates short strings, which are easily serialisable as JSON too.  We will initialise Temporal Durations using these ISO 8601 strings (like we saw earlier), then see how we can convert them to user friendly strings for our use case.  Finally we will sum all the tracks lengths using the Temporal API to get a total playing time for the LP (album).

## User Readable Durations

There is a `.toLocaleString()` method on Temporal Durations which works in a similar way to the equivalent Temporal Date and Time methods.  However, this relies on `Intl.DurationFormat` support.  That is another proposal which is not yet widely supported, so let&rsquo;s roll our own and see some Temporal Duration manipulation methods in the process.

Temporal objects have `minutes` and `seconds` fields which contain those values as numbers (rather that strings).  These let us write a simple function to convert the Temporal Duration objects to string for display:

```javascript
function stringFromDuration(iso8601Duration: string): string {
  const { minutes, seconds, } = Temporal.Duration.from(iso8601Duration);
  return `${minutes}:${seconds.toString(10).padStart(2, "0")}`;
}
```

This takes an input like `PT4M39S` and returns `4:39`.  We pad the seconds so that, for example, four minutes and two seconds gets written `4:02`, as would be expected by a user or site visitor.  We use this function to convert track lengths from ISO 8601 strings to the strings we see in the image.

## Temporal Duration Arithmetic

We can easily add durations using the `Temporal.Duration.add` method:

```javascript
const totalDuration = durationA.add(durationB);
```

That creates a new Temporal.Duration object.  For years, months and weeks, the intent could be ambiguous so you need also to <a aria-label="Read temporal add diocumentation for more detail" href="https://tc39.es/proposal-temporal/docs/duration.html#add">provide an object with a `relativeTo` date field</a> as a second argument.

We use `add` to work out the total track time using the <a aria-label="Open M D N docs on the array reduce method"  href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce">array reduce method</a>:

```javascript
const totalLength = tracks.reduce(
  (accumulator, { length }) => accumulator.add(Temporal.Duration.from(length)),
  new Temporal.Duration(),
);
```

Here `accumulator` keeps a running total of the duration as we loop through the members of the array.  Each array member is an object with a `length` field, the duration of the track as an ISO 8601 string.  We initialise the accumulator with `new Temporal.Duration()`, equivalent to zero duration.

You could do this manipulation manually by parsing the durations and converting them to seconds, summing and then converting the output to human readable string. That is no way to live your life though!  More seriously, using the Temporal API Duration object should result in more robust, less error prone code which is also cleaner and easier to understand.  There is a similar `subtract` method as well as absolute, rounding and negation methods.  See the <a aria-label="Open T C 39 docs on Temporal Duration methods" href="https://tc39.es/proposal-temporal/docs/duration.html">TC39 docs for more details</a>.

## 🙌🏽 Temporal API Duration: Wrapping Up

We have had an introduction to the Temporal API Duration.  In particular, we saw:

- how to **initialise a Temporal Duration** from an object or **ISO 8601** string,
- what an **ISO 8601 duration string is** ,
- also how you can sum durations using the **Temporal API**.

Open up the Astro project we referenced <a aria-label="Open the Temporal A P I duration project in the Rodney Lab Git Hub Repo" href="https://github.com/rodneylab/astro/tree/main/demos/temporal-api-duration">from the Rodney Lab GitHub repo to play around</a>.

I hope you found this article useful and am keen to hear how you will use the starter on your own projects as well as possible improvements.

## 🙏🏽 Temporal API Duration: Feedback

Have you found the post useful? Would you prefer to see posts on another topic instead? Get in touch with ideas for new posts. Also if you like my writing style, get in touch if I can write some posts for your company site on a consultancy basis. Read on to find ways to get in touch, further below. If you want to support posts similar to this one and can spare a few dollars, euros or pounds, please <a aria-label="Support Rodney Lab via Buy me a Coffee" href="https://rodneylab.com/giving/">consider supporting me through Buy me a Coffee</a>.

Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via <a aria-label"Reach out on Twitter" hef="https://twitter.com/messages/compose?recipient_id=1323579817258831875">@askRodney</a> on Twitter and also <a aria-label="Contact Rodney Lab via Telegram" href="https://t.me/askRodney">askRodney on Telegram</a>. Also, see <a aria-label="Get in touch with Rodney Lab" href="https://rodneylab.com/contact">further ways to get in touch with Rodney Lab</a>. I post regularly on <a aria-label="See posts on Astro" href="https://rodneylab.com/tags/astro/">Astro</a> as well as <a aria-label="See posts on svelte kit" href="https://rodneylab.com/tags/sveltekit/">SvelteKit</a>. Also <a aria-label="Subscribe to the Rodney Lab newsletter" href="https://rodneylab.com/about/#newsletter">subscribe to the newsletter to keep up-to-date</a> with our latest projects.