How to Display Time in a Human-Readable Format Using JavaScript’s Intl.RelativeTimeFormat

How to Display Time in a Human-Readable Format Using JavaScript’s Intl.RelativeTimeFormat
Photo by Djim Loic / Unsplash

When developing web applications, it's common to display time relative to the current moment. For example, showing how long ago an event occurred, or how soon something will happen, like "5 minutes ago" or "in 2 hours". JavaScript has an amazing built-in tool for this called Intl.RelativeTimeFormat. It's a feature designed to make handling relative time easy, especially when working with different locales.

If you're a beginner and not yet familiar with this, don't worry! In this article, we'll explore how to use this feature, why it's useful, and how to combine it with other JavaScript functions to calculate and format time.

What is Intl.RelativeTimeFormat?

Intl.RelativeTimeFormat is part of JavaScript’s internationalization (i18n) API, and it allows you to format relative time in a human-readable way. Instead of writing custom logic for things like "2 hours ago" or "in 3 days", this feature takes care of the formatting for you. Even better, it can format the time in different languages and handle localization.

Here’s a basic example of how it works:

const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });

console.log(rtf.format(-1, 'day'));  // "yesterday"
console.log(rtf.format(1, 'day'));   // "tomorrow"
console.log(rtf.format(-5, 'minute')); // "5 minutes ago"

In this example:

  • -1 for days means "yesterday".
  • 1 for days means "tomorrow".
  • -5 for minutes means "5 minutes ago".

The 'en' parameter tells the function to format the text in English. If we wanted to use a different language, such as French, we could easily switch it to 'fr':

const rtfFr = new Intl.RelativeTimeFormat('fr', { numeric: 'auto' });
console.log(rtfFr.format(-2, 'hour')); // "il y a 2 heures"

This flexibility makes it really powerful when building applications that need to support multiple languages.

How to Calculate Time Differences

While Intl.RelativeTimeFormat is great for formatting, it doesn’t calculate the time difference for you. You need to combine it with other JavaScript functions to determine the time gap between two dates. Usually, you’ll want to calculate the difference between now and some other date, then format that difference.

Here’s how you can do that:

function getRelativeTime(date) {
  const now = new Date();
  const pastDate = new Date(date);
  
  const diffInSeconds = Math.floor((pastDate - now) / 1000);
  const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });

  if (Math.abs(diffInSeconds) < 60) {
    return rtf.format(diffInSeconds, 'second');
  }

  const diffInMinutes = Math.floor(diffInSeconds / 60);
  if (Math.abs(diffInMinutes) < 60) {
    return rtf.format(diffInMinutes, 'minute');
  }

  const diffInHours = Math.floor(diffInMinutes / 60);
  if (Math.abs(diffInHours) < 24) {
    return rtf.format(diffInHours, 'hour');
  }

  const diffInDays = Math.floor(diffInHours / 24);
  return rtf.format(diffInDays, 'day');
}

In this function, we:

  • Calculate the time difference between the given date and the current time (now).
  • Convert that difference into seconds, minutes, hours, and days.
  • Use Intl.RelativeTimeFormat to output a readable string, like "2 hours ago" or "yesterday."

This approach makes your code much more readable and reusable, and you no longer need to manually write the logic for handling various time intervals.

What Happens with Larger Units?

You might have wondered: what about weeks, months, or even years? It's easy to extend the logic to handle these longer timeframes. Once you have the number of days, you can convert that into weeks, months, or years.

const diffInWeeks = Math.floor(diffInDays / 7);
if (Math.abs(diffInWeeks) < 4) {
  return rtf.format(diffInWeeks, 'week');
}

const diffInMonths = Math.floor(diffInWeeks / 4);
if (Math.abs(diffInMonths) < 12) {
  return rtf.format(diffInMonths, 'month');
}

const diffInYears = Math.floor(diffInMonths / 12);
return rtf.format(diffInYears, 'year');

With this addition, you can handle relative times like "last week", "in 3 months", or "2 years ago" without any extra hassle.

Important Points to Remember

  • Locale-specific formatting: One of the great things about Intl.RelativeTimeFormat is its locale support. You can easily switch between languages like 'en' (English) or 'fr' (French). This is essential for applications targeting a global audience.
  • Automatic singular/plural handling: The API automatically handles singular and plural forms for you. So you don’t need to worry about whether it should say "1 day ago" or "2 days ago"—it does that for you.
  • numeric: 'auto' vs. numeric: 'always': By default, using numeric: 'auto' allows for natural language terms like "yesterday" or "tomorrow". If you always want numeric values (e.g., "in 1 day" instead of "tomorrow"), you can use numeric: 'always'.
  • Time precision: Depending on your needs, you can choose to display time in seconds, minutes, hours, days, weeks, months, or years. This flexibility allows you to show time differences with the appropriate level of detail.

Finally

If you’re building an app that needs to display relative times in a user-friendly format, Intl.RelativeTimeFormat is an excellent tool. It simplifies formatting and localization, and when combined with a simple time difference calculation, it becomes a powerful feature for enhancing your app's user experience.

By using this API, you no longer need to write custom logic for displaying time in relation to the present, and you can focus more on other aspects of your application. Whether you're creating social media posts, task management tools, or event schedulers, Intl.RelativeTimeFormat will save you a lot of time and effort while providing a more natural and human-readable output for your users.

Support Us

Subscribe to Buka Corner

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe