53 lines
1.3 KiB
TypeScript
53 lines
1.3 KiB
TypeScript
type RelativeTimeOptions = {
|
|
now?: Date;
|
|
locale?: string;
|
|
};
|
|
|
|
export function formatRelativeTime(value: string | null | undefined, options?: RelativeTimeOptions): string {
|
|
if (!value) {
|
|
return '';
|
|
}
|
|
|
|
const date = new Date(value);
|
|
if (Number.isNaN(date.getTime())) {
|
|
return value;
|
|
}
|
|
|
|
const now = options?.now ?? new Date();
|
|
const diffSeconds = Math.round((date.getTime() - now.getTime()) / 1000);
|
|
const absSeconds = Math.abs(diffSeconds);
|
|
const rtf = new Intl.RelativeTimeFormat(options?.locale, { numeric: 'auto' });
|
|
|
|
if (absSeconds < 60) {
|
|
return rtf.format(diffSeconds, 'second');
|
|
}
|
|
|
|
const diffMinutes = Math.round(diffSeconds / 60);
|
|
if (Math.abs(diffMinutes) < 60) {
|
|
return rtf.format(diffMinutes, 'minute');
|
|
}
|
|
|
|
const diffHours = Math.round(diffMinutes / 60);
|
|
if (Math.abs(diffHours) < 24) {
|
|
return rtf.format(diffHours, 'hour');
|
|
}
|
|
|
|
const diffDays = Math.round(diffHours / 24);
|
|
if (Math.abs(diffDays) < 7) {
|
|
return rtf.format(diffDays, 'day');
|
|
}
|
|
|
|
const diffWeeks = Math.round(diffDays / 7);
|
|
if (Math.abs(diffWeeks) < 4) {
|
|
return rtf.format(diffWeeks, 'week');
|
|
}
|
|
|
|
const diffMonths = Math.round(diffDays / 30);
|
|
if (Math.abs(diffMonths) < 12) {
|
|
return rtf.format(diffMonths, 'month');
|
|
}
|
|
|
|
const diffYears = Math.round(diffDays / 365);
|
|
return rtf.format(diffYears, 'year');
|
|
}
|