Showing Relative Time using JS Intl. API

Basic understanding of Date object

According to MDN :

A JavaScript date is fundamentally specified as the time in milliseconds that has elapsed since the epoch, which is defined as the midnight at the beginning of January 1, 1970, UTC (equivalent to the UNIX epoch). This timestamp is timezone-agnostic and uniquely defines an instant in history.

We know that we can get the current time using Date.now(). Which will return us the number of milliseconds elapsed since midnight at the beginning of January 1, 1970, UTC.

Usually, the date time is stored in the database in the UNIX timestamp.

UNIX timestamp is the number of seconds passed from January 1, 1970.

Converting timestamp to time passed (day, minutes and seconds)

Let's take an example where we have a Facebook post and we need to show the relative time string in it. If the post was made on 17-05-2023 and today is 19-05-2023. It should show 2 days ago on the post. And yesterday if it was posted on the 18th.

First, we will calculate the time between the time of the post and the current time.

We get the UNIX timestamp of the post from the server and we can get the current time from Date.now().

We will convert the UNIX timestamp (which is in seconds ) to milliseconds. Date.now() returns us the time in milliseconds.

we can calculate the time passed in milliseconds from the time of the post with -

let currentTimestamp = Date.now();
let postTimestamp = getPostDateFromServer()*1000 //GET Post time from server

let timePassedInMilliseconds = currentTimestamp - postTimestamp

Now we have the timePassedInMilliseconds, We can use it to calculate if the post was made how many days, minutes or seconds ago. We will show X days ago, if days are more than 0 else we will show him X hours ago and so on.

We can show the user years and months as well but we are going till days only. If days are more than 30. We show 31 days ago and not 1 month ago.

Let's first calculate how many milliseconds are there in one (day, hour, minute and second)

let millsecInOneSec=1000;
let millsecInOneMinute=60*millsecInOneSec;
let millsecInOneHour=60*millsecInOneMinute;
let millsecInOneDay=24*millsecInOneHour;

Now we take timePassedInMilliseconds from the time of post and calculate days, hours and minutes passed.

We can calculate the unitsOfTimePassed by timeframe / millsecInTimeframe, then we can Math.floor unitsOfTimePassed to show only the unit and not its fractional part.

let unitsOfTimePassed; 
let timePassedString;
let daysPassed = timePassedInMilliseconds/millsecInOneDay;
let hoursPassed = timePassedInMilliseconds/millisecInOneHour;
let minPassed = timePassedInMilliseconds/millisecInOneMin;
let secPassed = timePassedInMilliseconds/millisecInOneSec;

let unitTypes=['day','hour','minute','second']
let displayUnitType;

if(daysPassed>1){
unitsOfTimePassed = Math.floor(daysPassed) 
displayUnitType=unitTypes[0]
//Math.floor() so that it does not show 1.x days ago , we want non-decimal value for time passed
}
else if(hoursPassed>1){
unitsOfTimePassed = Math.floor(hoursPassed) 
displayUnitType=unitTypes[1]
}
else if(minPassed>1){
unitsOfTimePassed = Math.floor(minPassed) 
displayUnitType=unitTypes[2]
}
else{
unitsOfTimePassed = Math.floor(secPassed) 
displayUnitType=unitTypes[3]
}

Now that we have unitsOfTimePassed, we can make our Relative Time String. For this, we will use Intl API. Specifically Intl.RelativeTimeFormat.

What is Intl API ??

Let's know what Intl (internationalization) is,

According to MDN it

The Intl namespace object contains several constructors as well as functions common to the internationalization constructors and other language-sensitive functions. Collectively, they comprise the ECMAScript Internationalization API, which provides language-sensitive string comparison, number formatting, date and time formatting, and more.

In simple words, it provides proper strings for units like (date, time, number, and quantity) which are compatible with different languages and writing styles in various regions.

Eg :

We can have a news website where we show dates of news in different regions in different languages for that we can use Intl.DateTimeFormat.

const date =Date.now();
const options={
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "numeric",
}
console.log(new Intl.DateTimeFormat('en-US',options).format(date));
// "Friday, May 19, 2023"

console.log(new Intl.DateTimeFormat('hi',options).format(date))
//"शुक्रवार, 19 मई 2023"

Notice in the first log we have used locale as 'en-US', so it uses a US-style date. While in the second log, we have 'hi' which is Hindi. Which makes the date in Indian Hindi format. In the Date, the day (19) comes first and then the month because that's the style that Hindi follows, while in 'en-US' month (May) comes first.

There are many other ways we can use intl api like Intl.Collator, Intl.ListFormat, Intl.NumberFormat, Intl.PluralRules etc.

Using Intl API to covert the time passed into Relative Time

We will be using Intl.RelativeTimeFormat to get the relative time string for the time passed since we made the post.

We already know unitsOfTimePassed and displayUnitType so we can get the string by :

const locales='en'
const options={
  numeric: "auto", // other values: "auto"
  style: "long", // other values: "short" or "narrow"
}
const rtf = new Intl.RelativeTimeFormat(locales,options);

We configure the Intl.RelativeTimeFormat options and locales according to our needs.

const displayString = rtf.format(-1 * unitsOfTimePassed,displayUnitType  ); // "n units of times ago

We put -1 to tell the rtf that the time has passed. To show an upcoming date we can give +1.

Now we can use the display string in the post to show the user the relative time from when the post was posted.


IF YOU LIKED THE POST DO SHARE IT 😄.