From a02c600858aec1df0bf2d5e437c2cdc9ce120cdc Mon Sep 17 00:00:00 2001 From: Jurgis Sakalauskas Date: Wed, 15 Oct 2025 08:38:39 +0300 Subject: [PATCH] add missing --- client/src/utils/relative-time.ts | 56 +++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 client/src/utils/relative-time.ts diff --git a/client/src/utils/relative-time.ts b/client/src/utils/relative-time.ts new file mode 100644 index 0000000..33fbd95 --- /dev/null +++ b/client/src/utils/relative-time.ts @@ -0,0 +1,56 @@ +const relativeTimeFormatter = new Intl.RelativeTimeFormat('en', { + numeric: 'auto' +}); + +const SECOND = 1; +const MINUTE = 60 * SECOND; +const HOUR = 60 * MINUTE; +const DAY = 24 * HOUR; +const WEEK = 7 * DAY; +const MONTH = 30 * DAY; +const YEAR = 365 * DAY; + +interface Threshold { + limit: number; + divisor: number; + unit: Intl.RelativeTimeFormatUnit; +} + +const thresholds: Threshold[] = [ + { limit: MINUTE, divisor: SECOND, unit: 'second' }, + { limit: HOUR, divisor: MINUTE, unit: 'minute' }, + { limit: DAY, divisor: HOUR, unit: 'hour' }, + { limit: WEEK, divisor: DAY, unit: 'day' }, + { limit: MONTH, divisor: WEEK, unit: 'week' }, + { limit: YEAR, divisor: MONTH, unit: 'month' }, + { limit: Infinity, divisor: YEAR, unit: 'year' } +]; + +const parseDateInput = (input: Date | string | number): Date | null => { + if (input instanceof Date) { + return Number.isNaN(input.getTime()) ? null : input; + } + + const parsed = new Date(input); + return Number.isNaN(parsed.getTime()) ? null : parsed; +}; + +export function formatRelativeTime(input: Date | string | number): string { + const targetDate = parseDateInput(input); + + if (!targetDate) { + return ''; + } + + const diffInSeconds = Math.round((targetDate.getTime() - Date.now()) / 1000); + const absoluteSeconds = Math.abs(diffInSeconds); + + for (const { limit, divisor, unit } of thresholds) { + if (absoluteSeconds < limit) { + const value = Math.round(diffInSeconds / divisor); + return relativeTimeFormatter.format(value, unit); + } + } + + return ''; +}