Skip to Content
Course content

205: Working with Relative Time Formatting

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you're meeting a friend for coffee. If they text you and say, "I'll be there on October 14th at 2:15 PM," and today is October 14th, you'd probably think they were a bit weird. In a real conversation, they'd just say, "I'll be there in 15 minutes." We naturally think in offsets from "now" rather than absolute coordinates on a calendar.

In JavaScript, we have the Intl.RelativeTimeFormat object to help us mimic this human behavior. It's essentially a translation layer. You give it a number (the offset) and a unit (like days or seconds), and it gives you back a string that makes sense to a human being in their own language.

Turning Numbers into Human Language

The core of this API is the format method. You don't pass it a Date object—which is a common point of confusion I see—you pass it the difference between two dates.

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

console.log(rtf.format(-1, 'day')); // "1 day ago"
console.log(rtf.format(2, 'hour')); // "in 2 hours"
console.log(rtf.format(-5, 'minute')); // "5 minutes ago"

Notice how negative numbers represent the past and positive numbers represent the future. It's a simple mapping: -1 day is yesterday; 1 day is tomorrow. I usually recommend initializing the RelativeTimeFormat object once and reusing it throughout your app rather than creating a new one every time you format a string. It's much better for performance.

The Magic of the 'auto' Style

One of my favorite parts of this API is the numeric option. If you set it to 'always', you get the literal number (e.g., "1 day ago"). But if you set it to 'auto', JavaScript will use a more natural term if one exists in that language.

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

console.log(rtfAuto.format(-1, 'day')); // "yesterday"
console.log(rtfAuto.format(0, 'day'));  // "today"
console.log(rtfAuto.format(1, 'day'));  // "tomorrow"

This is where the Intl object really shines. If you change the locale to 'es' (Spanish), -1, 'day' automatically becomes "ayer". You don't have to write a massive switch statement or maintain a translation JSON file for basic time phrases.

Bridging the Gap Between Dates and Relative Strings

Here is the catch: Intl.RelativeTimeFormat doesn't actually do any date math. It doesn't know what "now" is; it just knows how to format a number you give it. To make this useful in a real app—like a social media feed—you have to calculate the difference yourself.

I usually handle this by subtracting the timestamps (in milliseconds) and dividing by the appropriate constant. Here is a quick way to handle a "posted X minutes ago" scenario:

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

  // We can check the magnitude to decide which unit to use
  if (Math.abs(diffInSeconds) < 60) {
    return rtf.format(diffInSeconds, 'second');
  }
  
  const diffInMinutes = Math.floor(diffInSeconds / 60);
  return rtf.format(diffInMinutes, 'minute');
}

const postDate = new Date(Date.now() - 120000); // 2 minutes ago
console.log(formatRelativeTime(postDate)); // "2 minutes ago"

You'll notice I used Math.abs(). This is important because whether the date is in the past or future, you need to know the absolute scale of the difference to decide if you should be talking in seconds, minutes, or days.




📋 Practical Task

Build a Dynamic Social Media Timestamp Formatter

Create a function called getSmartTimestamp(date). This function should take a Date object as an argument and return a human-readable relative string using Intl.RelativeTimeFormat with the numeric: 'auto' option.

Your function must implement the following logic to choose the correct unit:

  • If the difference is less than 60 seconds, use 'second'.
  • If the difference is less than 60 minutes, use 'minute'.
  • If the difference is less than 24 hours, use 'hour'.
  • Otherwise, use 'day'.

Test your function with these three scenarios:

  1. A date from 30 seconds ago.
  2. A date from 3 hours ago.
  3. A date from exactly 1 day ago (should return "yesterday").
Rating
0 0

There are no comments for now.

to be the first to leave a comment.