JS protip: Formatting date/time ranges
By Christophe Porteneuve • Published on Oct 27, 2022

Last updated on January 31, 2023, 04:04pm

This post is also available in French.

Yesterday we covered formatting dates and times, today we'll learn how to format ranges of dates and times, in a clean and spiffy way!

formatRange(), the GOAT

Too few people noticed that DateTimeFormat was later enhanced with range management, which is super handy when formatting meetings, events, etc. where their timing has a beginning and an end.

I myself had to implement that kind of behavior (e.g. in Ruby) and believe you me, for it to work well and look nice, it's a pain in the neck: depending on whether both boundaries are on the same day, or month, or year, etc. means we don't want to repeat every time component. Not to mention short formats (using en dashes in French for instance) vs. long formats (e.g. “from...to...”). This quickly spirals out of control.

But no longer!

// 🤩 RAAAAAAAANGES!

const datesFR = new Intl.DateTimeFormat('fr-FR', { dateStyle: 'medium' })
const stampsFR = new Intl.DateTimeFormat('fr-FR', {
  dateStyle: 'long',
  timeStyle: 'short',
})

const datesUS = new Intl.DateTimeFormat('en-US', { dateStyle: 'medium' })
const stampsDE = new Intl.DateTimeFormat('de-DE', {
  dateStyle: 'long',
  timeStyle: 'short',
})

const oct26 = new Date(2022, 9, 26, 9)
const oct26pm = new Date(2022, 9, 26, 15)
const oct28 = new Date(2022, 9, 28, 9)
const nov4 = new Date(2022, 10, 4, 23, 11)
const may18 = new Date(2023, 4, 18, 23, 10)

datesFR.formatRange(oct26, oct26) // => '26 oct. 2022' (smart enough not to repeat anything)
datesFR.formatRange(oct26, oct28) // => '26–28 oct. 2022' (only distinct days)
datesFR.formatRange(oct26, nov4) // => '26 oct. – 4 nov. 2022' (distinct month+day)
datesFR.formatRange(oct26, may18) // => '26 oct. 2022 – 18 mai 2023' (distinct everything)

stampsFR.formatRange(oct26, oct26) // => '26 octobre 2022 à 09:00'
stampsFR.formatRange(oct26, oct26pm) // => '26 octobre 2022, 09:00 – 15:00'
stampsFR.formatRange(oct26, oct28) // => '26 octobre 2022 à 09:00 – 28 octobre 2022 à 09:00'

datesUS.formatRange(oct26, oct28) // => 'Oct 26 – 28, 2022'
datesUS.formatRange(oct26, nov4) // => 'Oct 26 – Nov 4, 2022'
datesUS.formatRange(oct26, may18) // => 'Oct 26, 2022 – May 18, 2023'

stampsDE.formatRange(oct26, oct26pm) // => '26. Oktober 2022, 09:00–15:00 Uhr'
stampsDE.formatRange(oct26, nov4) // => '26. Oktober 2022 um 09:00 – 4. November 2022 um 23:11'

Notice how German has a massive format variation depending on whether boundaries are on the same day or not? Honestly that kind of detail management gives me shivers!

Want to dive further?

You're in luck: besides yesterday's protip on date/time formatting, we've got a third one scheduled for tomorrow on time distances!

Where can I use that?

Well, everywhere. Taking into account everything in this 3-protips series, you're good to go with any browser released in, say, the past 3 years, plus Node 13+ and Deno 1.8+. So go for it!

Protips galore!

We got tons of articles and screencasts, with a lot more to come. Also check out our kick-ass training courses 🔥!

Check out our video courses! 🖥

Our screencasts are the ideal, affordable complement to our tech articles and in-room training courses, tackling Git, JavaScript and other topics. Check out these high-quality, affordable courses that are specially crafted to take on your biggest pain points and roadblocks.