import { getDateDaysDiff } from './dateDiffer'; import { Tooltip } from '../tooltip/Tooltip.component'; /** * @description Long date formatter, with weekday, year, month and day. Used for describing long term date. * @example Wednesday 06 October 2025 */ export const LONG_DATE_FORMATER = Intl.DateTimeFormat('en-GB', { weekday: 'long', year: 'numeric', month: 'long', day: '2-digit', }); /** * @description Long date formatter, without weekday. * @example 01 September 2025 */ export const LONG_DATE_FORMATER_WITHOUT_WEEKDAY = Intl.DateTimeFormat('en-GB', { year: 'numeric', month: 'long', day: '2-digit', }); /** * @description Date formatter, with year, month and day. Used for describing long term date. * @example 2025-01-01 */ export const DATE_FORMATER = Intl.DateTimeFormat('fr-CA', { year: 'numeric', month: '2-digit', day: '2-digit', hour12: false, }); /** * @description Day month formatter, with weekday, day and month. Used for describing long term date. * @example Wed 06 Oct */ export const DAY_MONTH_FORMATER = Intl.DateTimeFormat('en-GB', { weekday: 'short', day: '2-digit', month: 'short', }); /** * @description Time formatter, with hour, minute and second. Used for describing long term date. * @example 18:33:00 */ export const TIME_SECOND_FORMATER = Intl.DateTimeFormat('en-GB', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit', }); /** * @description Time formatter, with hour and minute. Used for describing long term date. * @example 18:33 */ export const TIME_FORMATER = Intl.DateTimeFormat('en-GB', { hour12: false, hour: '2-digit', minute: '2-digit', }); /** * @description Day month abbreviated formatter. Used for describing long term date. * @example 06 Oct */ export const DAY_MONTH_ABBREVIATED = Intl.DateTimeFormat('en-GB', { day: '2-digit', month: 'short', hour12: false, }); /** * @description Day month abbreviated formatter. Used for describing long term date. * @example 06 Oct 25 */ export const DAY_MONTH_ABBREVIATED_YEAR = Intl.DateTimeFormat('en-GB', { day: '2-digit', month: 'short', year: '2-digit', hour12: false, }); /** * @description Day month abbreviated hour minute second formatter. Used for describing long term date. * @example 06 Oct 18:33:00 */ export const DAY_MONTH_ABBREVIATED_HOUR_MINUTE_SECOND = Intl.DateTimeFormat( 'en-GB', { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, }, ); /** * @description Day month abbreviated hour minute formatter. Used for describing long term date. * @example 06 Oct 18:33 */ export const DAY_MONTH_ABBREVIATED_HOUR_MINUTE = Intl.DateTimeFormat('en-GB', { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit', hour12: false, }); /** * @description Day month abbreviated year hour minute formatter. Used for describing long term date. * @example 06 Oct 2025 18:33 */ export const DAY_MONTH_ABBREVIATED_YEAR_HOUR_MINUTE = Intl.DateTimeFormat( 'en-GB', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false, }, ); /** * @description Year month day formatter, without time. Used for describing long term date. * @example 2025-01-01 */ export const YEAR_MONTH_DAY_FORMATTER = Intl.DateTimeFormat('en-CA', { year: 'numeric', month: '2-digit', day: '2-digit', }); /** * @description Month day formatter, without year. Used for short term date ranges. * @example 01-15 */ export const MONTH_DAY_FORMATTER = Intl.DateTimeFormat('en-CA', { month: '2-digit', day: '2-digit', }); type FormattedDateTimeProps = { format: | 'date' | 'date-time' | 'date-time-second' | 'time' | 'time-second' | 'relative' | 'day-month-abbreviated-hour-minute' | 'day-month-abbreviated-hour-minute-second' | 'day-month-abbreviated-year-hour-minute' | 'long-date' | 'long-date-without-weekday' | 'chart-date' | 'year-month-day' | 'month-day' | 'day-month-abbreviated' | 'chart-long-term-date'; value: Date; }; const isItFutureOrIsItPast = ( timeDiff: number, stringToBeFormatted: string, ) => { if (timeDiff > 0) { return `${stringToBeFormatted} ago`; } else { return `in ${stringToBeFormatted}`; } }; /** * @description Formats the date and time according to the format specified. * @example * date: '2025-01-01' * 'date-time': '2025-01-01 00:00' * 'date-time-second': '2025-01-01 00:00:00' * time: '00:00' * 'time-second': '00:00:00' * relative: '1 month ago' * 'day-month-abbreviated-hour-minute': '06 Oct 18:33' * 'day-month-abbreviated-hour-minute-second': '06 Oct 18:33:00' * 'long-date': 'Wednesday 6 October 2025' * 'chart-date': '06 Oct' * 'year-month-day': '2025-10-06' */ export const FormattedDateTime = ({ format, value, }: FormattedDateTimeProps) => { switch (format) { case 'date': return <>{DATE_FORMATER.format(value)}; case 'date-time': return ( <>{DATE_FORMATER.format(value) + ' ' + TIME_FORMATER.format(value)} ); case 'date-time-second': return ( <> {DATE_FORMATER.format(value) + ' ' + TIME_SECOND_FORMATER.format(value)} ); case 'time': return <>{TIME_FORMATER.format(value)}; case 'time-second': return <>{TIME_SECOND_FORMATER.format(value)}; case 'relative': const now = new Date(); const monthDiff = getDateDaysDiff(value, now, 'months'); const dayDiff = getDateDaysDiff(value, now, 'days'); if (monthDiff !== 0 && Math.abs(dayDiff) > 90) { return ( } > {isItFutureOrIsItPast( monthDiff, `${Math.abs(monthDiff)} month${ Math.abs(monthDiff) > 1 ? 's' : '' }`, )} ); } if (dayDiff !== 0) { return ( } > {isItFutureOrIsItPast( dayDiff, `${Math.abs(dayDiff)} day${Math.abs(dayDiff) > 1 ? 's' : ''}`, )} ); } const hourDiff = getDateDaysDiff(value, now, 'hours'); if (hourDiff !== 0) { return ( } > {isItFutureOrIsItPast( hourDiff, `${Math.abs(hourDiff)} hour${Math.abs(hourDiff) > 1 ? 's' : ''}`, )} ); } const minuteDiff = getDateDaysDiff(value, now, 'minutes'); if (minuteDiff !== 0) { return ( } > {isItFutureOrIsItPast( minuteDiff, `${Math.abs(minuteDiff)} minute${ Math.abs(minuteDiff) > 1 ? 's' : '' }`, )} ); } return ( } > few seconds ago ); case 'day-month-abbreviated-hour-minute': return ( <> {DAY_MONTH_ABBREVIATED_HOUR_MINUTE.format(value) .replace(',', '') .replace(/Sept/g, 'Sep')} ); case 'day-month-abbreviated-hour-minute-second': return ( <> {DAY_MONTH_ABBREVIATED_HOUR_MINUTE_SECOND.format(value) .replace(',', '') // replace Sept with Sep to keep 3 letter month .replace(/Sept/g, 'Sep')} ); case 'long-date': return <>{LONG_DATE_FORMATER.format(value)}; case 'long-date-without-weekday': return <>{LONG_DATE_FORMATER_WITHOUT_WEEKDAY.format(value)}; case 'chart-date': return ( <> {DAY_MONTH_FORMATER.format(value) .replace(/[ ,]/g, '') // replace Sept with Sep to keep 3 letter month .replace(/Sept/g, 'Sep')} ); case 'year-month-day': return <>{YEAR_MONTH_DAY_FORMATTER.format(value)}; case 'month-day': return <>{MONTH_DAY_FORMATTER.format(value)}; case 'day-month-abbreviated-year-hour-minute': return ( <> {DAY_MONTH_ABBREVIATED_YEAR_HOUR_MINUTE.format(value) .replace(',', '') .replace(/Sept/g, 'Sep')} ); case 'day-month-abbreviated': return ( <> {DAY_MONTH_ABBREVIATED.format(value) .replace(',', '') .replace(/Sept/g, 'Sep')} ); case 'chart-long-term-date': return ( <> {DAY_MONTH_ABBREVIATED_YEAR.format(value) .replace(/[ ,]/g, '') // replace Sept with Sep to keep 3 letter month .replace(/Sept/g, 'Sep')} ); default: return <>; } };