DEV Community

Shubham Kumar
Shubham Kumar

Posted on

Converting date to relative time format in TypeScript

If you are developing an application which has to display timestamp for posts/comments/notifications, you might come across this requirement where you have to format time in "from now" format. This is sometimes called timeago or relative time.

You can either use a third party library like dayjs or momentjs for this, but for small projects, it is better to come up with your own utility function. In this tutorial we will write a util function which will accept a javascript Date object/ a string in ISO YYYY-MM-DD format/ or a date timestamp and convert it to relative time.

Eg:  2020-10-15 will be converted to "an year ago"
Enter fullscreen mode Exit fullscreen mode

JavaScript Date objects represent a single moment in time in a platform-independent format.It is is fundamentally specified as the number of milliseconds that have elapsed since midnight on January 1, 1970, UTC.

To convert the an input date to relative format, first we will define our time boundries in unit which we want to keep out least count. I am taking it in seconds, so the smallest difference that my method can return will be in seconds.

const units = [
  { label: 'year', seconds: 31536000 },
  { label: 'month', seconds: 2592000 },
  { label: 'week', seconds: 604800 },
  { label: 'day', seconds: 86400 },
  { label: 'hour', seconds: 3600 },
  { label: 'minute', seconds: 60 },
  { label: 'second', seconds: 1 }
];
Enter fullscreen mode Exit fullscreen mode

Let's write our util method now. We will input a date and find the difference between the input and the current moment. We can get the current date by using the Date API and calling the valueOf method on a new instance of Date object. The inout date is then subtracted from this value. Now we find the nearest unit to the input date. The method calculateTimeDifference will take the milliseconds equivalent of Date for simplifying calculations. The nearest unit will be the one which has the quotient greater than 1 as we have defined our units in decending order. Once we get the quotient greater than 1, we will return that value with the respective unit. That will be used to contruct our string. You can check the snippets below:

const timeAgo = (date: string | number | Date) => {
  const time = Math.floor(
    (new Date().valueOf() - new Date(date).valueOf()) / 1000
  );
  const { interval, unit } = calculateTimeDifference(time);
  const suffix = interval === 1 ? '' : 's';
  return `${interval} ${unit}${suffix} ago`;
};
Enter fullscreen mode Exit fullscreen mode
const calculateTimeDifference = (time: number) => {
  for (let { label, seconds } of units) {
    const interval = Math.floor(time / seconds);
    if (interval >= 1) {
      return {
        interval: interval,
        unit: label
      };
    }
  }
  return {
    interval: 0,
    unit: ''
  };
};
Enter fullscreen mode Exit fullscreen mode

Discussion (3)

Collapse
rammina profile image
Rammina

Thank you for sharing this information!

How about using libraries like date-fns? Wouldn't that make things simpler?
date-fns.org/
It also has type definition files for Typescript.

Collapse
shubhamkumar10 profile image
Shubham Kumar Author

Yes we can definitely use libraries, but the idea here was to write your own util function to keep the bundle size low. Adding a whole lib just to use a single function didn't make sense to me.

Collapse
rammina profile image
Rammina

True, I suppose if it's only a single functionality, a library would be overkill. Thank you!