import { addDays, addMonths, addYears, endOfMonth, endOfWeek, format, startOfMonth, startOfWeek, startOfYear, } from 'date-fns' import { utcToZonedTime } from 'date-fns-tz' import createI18n from '@/i18n' import { localeFromLanguage } from '@/utils/locales' const { locale } = createI18n.global export const getStartDate = ( duration: string, day: Date, weekStartingMonday: boolean ): Date => { switch (duration) { case 'week': return startOfWeek(day, { weekStartsOn: weekStartingMonday ? 1 : 0 }) case 'year': return startOfYear(day) case 'month': return startOfMonth(day) default: throw new Error( `Invalid duration, expected: "week", "month", "year", got: "${duration}"` ) } } export const incrementDate = (duration: string, day: Date): Date => { switch (duration) { case 'week': return addDays(day, 7) case 'year': return addYears(day, 1) case 'month': return addMonths(day, 1) default: throw new Error( `Invalid duration, expected: "week", "month", "year", got: "${duration}"` ) } } export const getDateWithTZ = (dateInUTC: string, tz: string): Date => { return utcToZonedTime(new Date(dateInUTC), tz) } export const getCalendarStartAndEnd = ( date: Date, weekStartingMonday: boolean ): Record => { const monthStart = startOfMonth(date) const monthEnd = endOfMonth(date) const weekStartsOn = weekStartingMonday ? 1 : 0 return { start: startOfWeek(monthStart, { weekStartsOn }), end: endOfWeek(monthEnd, { weekStartsOn }), } } export const formatWorkoutDate = ( dateTime: Date, dateFormat: string | null = null, timeFormat: string | null = null ): Record => { if (!dateFormat) { dateFormat = 'yyyy/MM/dd' } dateFormat = getDateFormat(dateFormat, locale.value) if (!timeFormat) { timeFormat = 'HH:mm' } return { workout_date: format(dateTime, dateFormat, { locale: localeFromLanguage[locale.value], }), workout_time: format(dateTime, timeFormat), } } const availableDateFormats = [ 'MM/dd/yyyy', 'dd/MM/yyyy', 'yyyy-MM-dd', 'date_string', ] export const dateStringFormats: Record = { de: 'do MMM yyyy', en: 'MMM. do, yyyy', fr: 'd MMM yyyy', it: 'd MMM yyyy', // nb: 'do MMM yyyy', nl: 'd MMM yyyy', } export const getDateFormat = (dateFormat: string, language: string): string => { return dateFormat === 'date_string' ? dateStringFormats[language] : dateFormat } export const formatDate = ( dateString: string, timezone: string, dateFormat: string, withTime = true, language: string | null = null, withSeconds = false ): string => { if (!language) { language = locale.value } const timeFormat = withTime ? (withSeconds ? ' HH:mm:ss' : ' HH:mm') : '' return format( getDateWithTZ(dateString, timezone), `${getDateFormat(dateFormat, language)}${timeFormat}`, { locale: localeFromLanguage[language] } ) } export const availableDateFormatOptions = ( inputDate: string, timezone: string, language: string | null = null ) => { const l: string = language ? language : locale.value const options: Record[] = [] availableDateFormats.map((df) => { const dateFormat = getDateFormat(df, l) options.push({ label: `${dateFormat} - ${formatDate( inputDate, timezone, dateFormat, false, l )}`, value: df, }) }) return options }