trypost/resources/js/date.ts

186 lines
5.8 KiB
TypeScript

import dayjs from '@/dayjs';
/**
* Obtém o timezone do usuário
* Tenta pegar do Inertia page props primeiro, senão usa o timezone do browser
*/
function getUserTimezone(): string {
return Intl.DateTimeFormat().resolvedOptions().timeZone;
}
export default {
formatDate(date: string | null | undefined) {
if (!date) return '-';
return dayjs.utc(date).tz(getUserTimezone()).format('LL');
},
formatDateTime(date: string) {
return dayjs
.utc(date)
.tz(getUserTimezone())
.format('D [de] MMM [de] YYYY [às] HH:mm');
},
formatTime(date: string | null | undefined) {
if (!date) return '-';
return dayjs.utc(date).tz(getUserTimezone()).format('HH:mm');
},
formatDateTimeForApi(date: string) {
// Convert from user timezone to UTC for API
return dayjs
.tz(date, getUserTimezone())
.utc()
.format('YYYY-MM-DD HH:mm:ss');
},
formatDateTimeForDatePicker(date: string) {
// Convert from UTC to user timezone for display
if (!date) return dayjs().tz(getUserTimezone());
return dayjs.utc(date).tz(getUserTimezone());
},
diffForHumans(date: string) {
const localDate = dayjs
.utc(date)
.tz(getUserTimezone())
.format('YYYY-MM-DD HH:mm:ss');
return dayjs().to(dayjs(localDate));
},
formatTimelineDate(dateStr: string) {
const d = dayjs(dateStr);
return {
day: d.date(),
month: d.format('MMM'),
year: d.year(),
};
},
formatDuration(duration: string) {
// Duration comes in format "HH:mm:ss"
const [hours, minutes] = duration.split(':');
const h = parseInt(hours, 10);
const m = parseInt(minutes, 10);
if (h > 0) {
return `${h}h ${m}min`;
}
return `${m}min`;
},
formatMedicalRecordDuration(startAt: string, duration: string | null) {
const startTime = this.formatTime(startAt);
if (!duration) {
return startTime;
}
const formattedDuration = this.formatDuration(duration);
return `${startTime} (${formattedDuration})`;
},
/**
* Converte horário de appointment de UTC para timezone do usuário
* Específico para agenda onde date e time vêm separados do banco
* @param date - Data no formato YYYY-MM-DD
* @param time - Horário no formato HH:mm:ss
* @returns Horário formatado no timezone do usuário (HH:mm)
*/
convertAppointmentTimeToUserTimezone(date: string, time: string): string {
return dayjs
.utc(`${date} ${time}`)
.tz(getUserTimezone())
.format('HH:mm');
},
/**
* Converte horário de appointment de UTC para timezone do usuário e retorna objeto dayjs
* Útil para cálculos de posicionamento na agenda
* @param date - Data no formato YYYY-MM-DD
* @param time - Horário no formato HH:mm:ss
* @returns Objeto dayjs no timezone do usuário
*/
getAppointmentDateTimeInUserTimezone(date: string, time: string) {
return dayjs.utc(`${date} ${time}`).tz(getUserTimezone());
},
/**
* Formata o nome do mês e ano
* @param month - Número do mês (1-12)
* @param year - Ano (ex: 2025)
* @returns String formatada (ex: "Fev/2025")
*/
formatMonthYear(month: number, year: number): string {
return dayjs(new Date(year, month - 1, 1)).format('MMM/YYYY');
},
formatAge(birthDate: string): string {
return dayjs().from(dayjs(birthDate), true);
},
/**
* Formata tempo decorrido em segundos para formato de stopwatch HH:MM:SS
* @param seconds - Tempo decorrido em segundos
* @returns String formatada (ex: "02:30:45", "00:05:12")
*/
formatStopwatch(seconds: number): string {
return dayjs.duration(seconds, 'seconds').format('HH:mm:ss');
},
/**
* Calcula tempo decorrido entre uma data UTC e o momento atual no timezone do usuário
* @param startDateTime - Data/hora de início em UTC (ISO string)
* @returns Tempo decorrido em segundos
*/
getElapsedSeconds(startDateTime: string): number {
const startTime = dayjs.utc(startDateTime).tz(getUserTimezone());
const now = dayjs().tz(getUserTimezone());
return now.diff(startTime, 'seconds');
},
/**
* Formata a data de build da aplicação no timezone do usuário
* @param date - Data/hora em ISO string (UTC)
* @returns String formatada (ex: "31/12/2025 14:25")
*/
formatBuildDate(date: string): string {
return dayjs.utc(date).tz(getUserTimezone()).format('DD/MM/YYYY HH:mm');
},
/**
* Obtém o timezone do usuário
* Tenta pegar do Inertia page props primeiro, senão usa o timezone do browser
* @returns Timezone do usuário
*/
getUserTimezone,
/**
* Formata uma data para o formato YYYY-MM-DD (usado em DatePicker)
* Evita problemas de timezone ao não criar objeto Date
* @param date - Data no formato YYYY-MM-DD ou ISO string
* @returns Data no formato YYYY-MM-DD
*/
formatDateForInput(date: string): string {
return dayjs(date).format('YYYY-MM-DD');
},
/**
* Formata minutos para formato legível
* @param minutes - Número de minutos
* @returns String formatada (ex: "1h", "1h 41min", "30min")
*/
formatMinutes(minutes: number): string {
const duration = dayjs.duration(minutes, 'minutes');
const h = duration.hours();
const m = duration.minutes();
if (h > 0 && m > 0) {
return `${h}h ${m}min`;
}
if (h > 0) {
return `${h}h`;
}
return `${m}min`;
},
};