Formatting relative times
Displaying '2 days ago' instead of a timestamp
Problem
An application displays a timestamp like 'Posted 2 days ago.' While this is clear in English, the logic and grammar for '2 days ago' versus 'in 2 days' (past vs. future) differ significantly across languages. A simple string concatenation (e.g., '2' + ' ' + 'days ago') fails to produce grammatically correct output.
Solution
Use a dedicated component like FormattedRelativeTime from react-intl. This component takes a numeric value (e.g., -2) and a unit (e.g., 'day'), and automatically formats it into a locale-aware, grammatically correct string such as '2 days ago', 'hace 2 días', or 'gestern' (yesterday).
Steps
1. Create a client component for relative time
The FormattedRelativeTime component must be used inside a client component.
Create a new file app/components/RelativeTime.tsx.
// app/components/RelativeTime.tsx
'use client';
import { FormattedRelativeTime } from 'react-intl';
type Props = {
value: number;
unit: Intl.RelativeTimeFormatUnit;
};
export default function RelativeTime({ value, unit }: Props) {
return (
<FormattedRelativeTime
value={value}
unit={unit}
numeric="auto" // "auto" allows "yesterday" or "tomorrow"
style="long"
/>
);
}
2. Pass formatting options
The FormattedRelativeTime component accepts several key props:
value: The number of units. A negative value (e.g.,-2) indicates the past ("2 days ago"), and a positive value (2) indicates the future ("in 2 days").unit: The unit of time, such as 'day', 'hour', 'minute', or 'second'.numeric="auto": This allows the library to use words like "yesterday" or "tomorrow" instead of "1 day ago" or "in 1 day".
3. Use the component on a page
You can now use this component on any page. You are responsible for calculating the time difference before passing the props.
// app/[lang]/page.tsx
import RelativeTime from '@/app/components/RelativeTime';
export default function Home() {
// You would calculate these values dynamically
const daysSinceUpdate = -2;
const hoursUntilEvent = 3;
return (
<div>
<h1>Updates</h1>
<p>
File updated: <RelativeTime value={daysSinceUpdate} unit="day" />
</p>
<p>
Event starts: <RelativeTime value={hoursUntilEvent} unit="hour" />
</p>
</div>
);
}
A user visiting /en will see "File updated: 2 days ago" and "Event starts: in 3 hours". A user visiting /es will see "File updated: hace 2 días" and "Event starts: dentro de 3 horas".