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 <>>;
}
};