import { getUserLocale, getUserLanguageCode } from 'utils/user-locale' import { getDateTimeFromISO, getNow, getTz, type DefaultOpts } from './datetime' // Reference: // Luxon and MomentJS vary in their formatting options // - Luxon: https://moment.github.io/luxon/#/formatting // - Moment: https://momentjs.com/docs/#/displaying/format/ /** * Date Format: `Relative` */ export const relativeDate = ( dateString: string, { now = getNow(), locale = getUserLocale(), timezone = getTz(), }: DefaultOpts = {} ): string => { const style = 'long' const dateTime = getDateTimeFromISO(dateString, { locale, timezone }) const diff = dateTime.diff(now, 'seconds').seconds if (Math.abs(diff) < 10 && 'RelativeTimeFormat' in Intl) { // Reference: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat return new Intl.RelativeTimeFormat(locale, { numeric: 'auto', style, }).format(0, 'second') } return dateTime.toRelative({ style, base: now, unit: ['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds'], round: true, padding: 500, // @ts-expect-error: `roundingMethod` added via patch roundingMethod: 'round', }) } /** * Date Format: `Relative (short)` */ export const relativeShort = ( dateString: string, { now = getNow(), locale = getUserLocale(), language = getUserLanguageCode(), timezone = getTz(), }: DefaultOpts = {} ): string => { const style = 'narrow' const dateTime = getDateTimeFromISO(dateString, { locale: language === 'en' ? 'en' : locale, timezone, }) const diff = dateTime.diff(now, 'seconds').seconds if (Math.abs(diff) < 10 && 'RelativeTimeFormat' in Intl) { // Reference: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat return new Intl.RelativeTimeFormat(locale, { numeric: 'auto', style, }).format(0, 'second') } return dateTime.toRelative({ style, base: now, unit: ['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds'], round: true, padding: 500, // @ts-expect-error: `roundingMethod` added via patch roundingMethod: 'round', }) } /** * Date Format: `Date / Time` */ export const absoluteDatetime = ( dateString: string, { locale = getUserLocale(), timezone = getTz() }: DefaultOpts = {} ): string => getDateTimeFromISO(dateString, { locale, timezone }).toFormat('D t') /** * Date Format: `Date (MM/DD/YYYY)` */ export const absoluteDate = ( dateString: string, { locale = getUserLocale(), timezone = getTz() }: DefaultOpts = {} ): string => getDateTimeFromISO(dateString, { locale, timezone }).toFormat('L/d/yyyy') /** * Date Format: `Date (DD/MM/YYYY)` */ export const universalDate = ( dateString: string, { locale = getUserLocale(), timezone = getTz() }: DefaultOpts = {} ): string => getDateTimeFromISO(dateString, { locale, timezone }).toFormat('d/L/yyyy') /** * Date Format: `Day of Week`/`Day of Week (short)` */ export const dayOfWeek = ( dateString: string, abbreviated: boolean, { locale = getUserLocale(), timezone = getTz() }: DefaultOpts = {} ): string => getDateTimeFromISO(dateString, { locale, timezone }).toFormat( abbreviated ? 'ccc' : 'cccc' ) /** * Date Format: `Day Number` */ export const dayNumber = ( dateString: string, { locale = getUserLocale(), timezone = getTz() }: DefaultOpts = {} ): string => getDateTimeFromISO(dateString, { locale, timezone }).toFormat('d') /** * Date Format: `Month Name`/`Month Name (short)` */ export const monthName = ( dateString: string, abbreviated: boolean, { locale = getUserLocale(), timezone = getTz() }: DefaultOpts = {} ): string => getDateTimeFromISO(dateString, { locale, timezone }).toFormat( abbreviated ? 'LLL' : 'LLLL' ) /** * Date Format: `Month Number` */ export const monthNumber = ( dateString: string, { locale = getUserLocale(), timezone = getTz() }: DefaultOpts = {} ): string => getDateTimeFromISO(dateString, { locale, timezone }).toFormat('M') /** * Date Format: `Year Number`/`Year Number (short)` */ export const yearNumber = ( dateString: string, abbreviated: boolean, { locale = getUserLocale(), timezone = getTz() }: DefaultOpts = {} ): string => getDateTimeFromISO(dateString, { locale, timezone }).toFormat( abbreviated ? 'yy' : 'yyyy' ) /** * Date Format: `Time` */ export const timeOnly = ( dateString: string, { locale = getUserLocale(), timezone = getTz() }: DefaultOpts = {} ): string => getDateTimeFromISO(dateString, { locale, timezone }).toFormat('t') /** * Date Format: `No Formatting` (date-time fields) */ export const isoDateTime = ( dateString: string, { locale = getUserLocale() }: DefaultOpts = {} ): string => getDateTimeFromISO(dateString, { locale, timezone: 'UTC' }).toISO({ suppressMilliseconds: true, }) /** * Date Format: `No Formatting` (date-only fields) */ export const isoDateOnly = ( dateString: string, { locale = getUserLocale() }: DefaultOpts = {} ): string => getDateTimeFromISO(dateString, { locale, timezone: 'UTC' }).toISODate()