arbret/frontend/app/utils/date.ts
counterweight a5b941e748
Fix timezone issue in formatDateTime for appointments page
- Changed formatDateTime to use UTC methods instead of toLocaleString
- Prevents timezone conversion when displaying appointment times
- Now booking at 11:45 shows as 11:45 in appointments page, not 12:45
- Consistent with formatTime which already uses UTC
- Manual formatting to match previous format: 'Mon, Jan 15, 11:45'
2025-12-21 18:18:40 +01:00

89 lines
2.7 KiB
TypeScript

/**
* Shared date formatting utilities.
*/
/**
* Format date as YYYY-MM-DD in local timezone.
*/
export function formatDate(d: Date): string {
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
/**
* Format time from ISO string to HH:MM format in UTC.
* Uses UTC to avoid timezone conversion issues when displaying booking slots.
*/
export function formatTime(isoString: string): string {
const d = new Date(isoString);
// Use UTC methods to avoid timezone conversion
const hours = String(d.getUTCHours()).padStart(2, "0");
const minutes = String(d.getUTCMinutes()).padStart(2, "0");
return `${hours}:${minutes}`;
}
/**
* Format datetime from ISO string to a readable format in UTC.
* Uses UTC to avoid timezone conversion issues when displaying appointment times.
*/
export function formatDateTime(isoString: string): string {
const d = new Date(isoString);
// Use UTC methods to avoid timezone conversion
const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const weekday = weekdays[d.getUTCDay()];
const month = months[d.getUTCMonth()];
const day = d.getUTCDate();
const hours = String(d.getUTCHours()).padStart(2, "0");
const minutes = String(d.getUTCMinutes()).padStart(2, "0");
return `${weekday}, ${month} ${day}, ${hours}:${minutes}`;
}
/**
* Format date for display (e.g., "Mon, Jan 15").
*/
export function formatDisplayDate(d: Date): string {
return d.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
}
/**
* Format time string from "HH:MM:SS" or "HH:MM" format to "HH:MM".
* Avoids string slicing by properly parsing the time.
*/
export function formatTimeString(timeStr: string): string {
// Handle both "HH:MM:SS" and "HH:MM" formats
const parts = timeStr.split(":");
if (parts.length >= 2) {
return `${parts[0].padStart(2, "0")}:${parts[1].padStart(2, "0")}`;
}
return timeStr;
}
/**
* Get date range for booking/availability (from minAdvanceDays to maxAdvanceDays).
* Returns an array of Date objects starting from minAdvanceDays days from today.
*/
export function getDateRange(minAdvanceDays: number, maxAdvanceDays: number): Date[] {
const dates: Date[] = [];
const today = new Date();
for (let i = minAdvanceDays; i <= maxAdvanceDays; i++) {
const d = new Date(today);
d.setDate(today.getDate() + i);
dates.push(d);
}
return dates;
}
/**
* Check if a date is a weekend (Saturday or Sunday).
*/
export function isWeekend(date: Date): boolean {
const day = date.getDay();
return day === 0 || day === 6;
}