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"
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 }
];
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`;
};
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: ''
};
};
Top comments (3)
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.
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.
True, I suppose if it's only a single functionality, a library would be overkill. Thank you!