Create a component in React that takes time as input and returns a string representing the time in the human-readable format like “just now”, “a few secs ago”, “a minute ago”, “10 mins ago”, etc.
Example
Input:
<FormattedTime time={new Date("Sun Nov 20 2022 14:20:59")} />
Output:
3 hours ago
This component requires calculating the difference between two times efficiently and then showing the appropriate message.
Get a time as input and get the difference between it with the current time in seconds.
// get the current time in milliseconds const current = +Date.now(); // get the date in milliseconds const lastTime = +lastDate; // get the difference in milliseconds let diff = Math.abs(current - lastTime); // convert the time to seconds diff = diff / 1000;
Create an enum of times in seconds and the messages.
// messages
const messages = {
NOW: "just now",
LESS_THAN_A_MINUTE: "a few secs ago",
LESS_THAN_5_MINUTES: "a minute ago",
MINUTES: "mins ago",
HOURS: "hours ago",
DAYS: "days ago",
MONTHS: "months ago",
YEARS: "years ago",
};
// time in seconds
const timeInSecond = {
MINUTE: 60,
HOUR: 60 * 60,
DAY: 24 * 60 * 60,
MONTH: 30 * 24 * 60 * 60,
YEAR: 365 * 24 * 60 * 60,
};
Check, in which range do times fit and return the message accordingly.
// convert the time to the human-readable format
switch (diff) {
case diff < 10:
return messages.NOW;
case diff > 10 && diff < timeInSecond.MINUTE:
return messages.LESS_THAN_A_MINUTE;
case diff > timeInSecond.MINUTE && diff < timeInSecond.MINUTE * 5:
return messages.LESS_THAN_5_MINUTES;
default:
if (diff < timeInSecond.HOUR) {
return `${getFormatted(diff / timeInSecond.MINUTE)} ${messages.MINUTES}`;
} else if (diff > timeInSecond.HOUR && diff < timeInSecond.DAY) {
return `${getFormatted(diff / timeInSecond.HOUR)} ${messages.HOURS}`;
} else if (diff > timeInSecond.DAY && diff < timeInSecond.MONTH) {
return `${getFormatted(diff / timeInSecond.DAY)} ${messages.DAYS}`;
} else if (diff > timeInSecond.MONTH && diff < timeInSecond.YEAR) {
return `${getFormatted(diff / timeInSecond.MONTH)} ${messages.MONTHS}`;
} else if (diff > timeInSecond.YEAR) {
return `${getFormatted(diff / timeInSecond.YEAR)} ${messages.YEARS}`;
}
}
Encapsulate this logic inside a function that will format and return the value.
// messages
const messages = {
NOW: "just now",
LESS_THAN_A_MINUTE: "a few secs ago",
LESS_THAN_5_MINUTES: "a minute ago",
MINUTES: "mins ago",
HOURS: "hours ago",
DAYS: "days ago",
MONTHS: "months ago",
YEARS: "years ago",
};
// time in seconds
const timeInSecond = {
MINUTE: 60,
HOUR: 60 * 60,
DAY: 24 * 60 * 60,
MONTH: 30 * 24 * 60 * 60,
YEAR: 365 * 24 * 60 * 60,
};
// get the floor value
const getFormatted = (time) => {
return Math.floor(time);
};
// helper function to calculate
const calculate = (lastDate) => {
// get the current time in milliseconds
const current = +Date.now();
// get the date in milliseconds
const lastTime = +lastDate;
// get the difference in milliseconds
let diff = Math.abs(current - lastTime);
// convert the time to seconds
diff = diff / 1000;
// convert the time to the human-readable format
switch (diff) {
case diff < 10:
return messages.NOW;
case diff > 10 && diff < timeInSecond.MINUTE:
return messages.LESS_THAN_A_MINUTE;
case diff > timeInSecond.MINUTE && diff < timeInSecond.MINUTE * 5:
return messages.LESS_THAN_5_MINUTES;
default:
if (diff < timeInSecond.HOUR) {
return `${getFormatted(diff / timeInSecond.MINUTE)} ${messages.MINUTES}`;
} else if (diff > timeInSecond.HOUR && diff < timeInSecond.DAY) {
return `${getFormatted(diff / timeInSecond.HOUR)} ${messages.HOURS}`;
} else if (diff > timeInSecond.DAY && diff < timeInSecond.MONTH) {
return `${getFormatted(diff / timeInSecond.DAY)} ${messages.DAYS}`;
} else if (diff > timeInSecond.MONTH && diff < timeInSecond.YEAR) {
return `${getFormatted(diff / timeInSecond.MONTH)} ${messages.MONTHS}`;
} else if (diff > timeInSecond.YEAR) {
return `${getFormatted(diff / timeInSecond.YEAR)} ${messages.YEARS}`;
}
}
};
const FormattedTime = ({ time }) => {
// calculate the time
const convertedTime = calculate(time);
return <p>{convertedTime}</p>;
};
export default FormattedTime;
Input:
<FormattedTime time={new Date("Sun Nov 20 2022 14:20:59")} />
Output:
3 hours ago