👨‍🚀 Traversing Time with Intl.RelativeTimeFormat()

Dominic Magnifico - Dec 18 '23 - - Dev Community

For the longest time working with dates in JavaScript was a huge pain. That’s why libraries such as moment.js or date-fns are so popular. A lot of times I’d reach for these libraries when working with relative time formatting, but since late last year we’ve had pretty great browser support for the RelativeTimeFormat() method. In my mind, relative dates are just more visually appealing, especially for working with dates internationally. Dates like "5 days ago" or "in 2 months" are far more intuitive for users than 12/12/2023, or 03/11/2027. Folks in the US will see that as March 11, 2027, whereas the rest of the world will see that as November 03, 2027. What a nightmare.

Time Travel Made Easy 🕰️

Temporal expressions in applications often require expressing time durations relative to the present moment. Imagine you're building an app where users view upcoming events. Instead of displaying specific dates, you opt for a cleaner interface showing how far in the future or past the events occur.

Using Intl.RelativeTimeFormat(), we can format these temporal distinctions in a much better way. Suppose there's an event happening tomorrow. By employing this method, you transform "1 day”, or “12/19/2023” into the more user-friendly "tomorrow." Even better, for an event that occurred last week, "7 days ago" smoothly transitions into "last week”. This helps our users to not have to do mental calculus to figure out when the event happened. Let’s check out some code:

const timeFormatter = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
const timeUntilEvent = -1; // Negative value for past events
const formattedTime = timeFormatter.format(timeUntilEvent, 'day');
// Output: "yesterday"
Enter fullscreen mode Exit fullscreen mode

In this example, Intl.RelativeTimeFormat() simplifies the representation of temporal information, offering a clearer and more engaging experience for users interacting with dates.

Let’s try another more robust example where we’re receiving a formatted date string via an object. We’ll also automatically determine when to use the appropriate unit in the relative time internationalized message. Thanks to Steve Sewell's post for providing a bit of inspiration for the following snippet:

// Assume we have a date string being received from some object.
const data = {
  formattedDate: "2023-12-18T08:00:00Z" // Example date string in ISO 8601 format
};

// Extract the formatted date string from the object
const { formattedDate } = data;

// Convert the date string to a Date object
const dateObject = new Date(formattedDate);

// Calculate the difference in seconds between the given date and the current date
const secondsDiff = Math.round((dateObject - Date.now()) / 1000);

// Array representing one minute, hour, day, week, month, etc. in seconds
const unitsInSec = [60, 3600, 86400, 86400 * 7, 86400 * 30, 86400 * 365, Infinity];

// Array equivalent to the above but in the string representation of the units
const unitStrings = ["second", "minute", "hour", "day", "week", "month", "year"];

// Find the appropriate unit based on the seconds difference
const unitIndex = unitsInSec.findIndex((cutoff) => cutoff > Math.abs(secondsDiff));

// Get the divisor to convert seconds to the appropriate unit
const divisor = unitIndex ? unitsInSec[unitIndex - 1] : 1;

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

// Format the relative time based on the calculated unit
const relativeTime = rtf.format(Math.floor(secondsDiff / divisor), unitStrings[unitIndex]);

console.log(relativeTime);
// Output: "9 hours ago"
Enter fullscreen mode Exit fullscreen mode

We can wrap this in a nice little utility function if we wish to reuse it in different parts of our application. But now, any date string that we receive, we can convert to relative time nice and easily!

The Temporal Shift 💡

Intl.RelativeTimeFormat() opens doors to crafting intuitive and localized temporal expressions. Think of social media feeds, news articles, or e-commerce platforms. Tailoring timestamps like "a few minutes ago" or "next month" not only enhances readability but also transcends language barriers, offering a seamless user experience worldwide.

Integrating this method isn't just about displaying time; it's about communicating contextually relevant time-based information, and refining the overall user interface.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .