Files
DentalManagementE/apps/Frontend/src/utils/dateUtils.ts
2025-07-22 22:37:23 +05:30

101 lines
3.5 KiB
TypeScript

/**
* Parse a date string in yyyy-MM-dd format (assumed local) into a JS Date object.
* No timezone conversion is applied. Returns a Date at midnight local time.
*/
export function parseLocalDate(input: string | Date): Date {
if (input instanceof Date) {
return new Date(input.getFullYear(), input.getMonth(), input.getDate());
}
if (typeof input === "string") {
const dateString = input?.split("T")[0] ?? "";
const parts = dateString.split("-");
const [yearStr, monthStr, dayStr] = parts;
// Validate all parts are defined and valid strings
if (!yearStr || !monthStr || !dayStr) {
throw new Error("Invalid date string format. Expected yyyy-MM-dd.");
}
const year = parseInt(yearStr, 10);
const month = parseInt(monthStr, 10) - 1; // JS Date months are 0-based
const day = parseInt(dayStr, 10);
if (Number.isNaN(year) || Number.isNaN(month) || Number.isNaN(day)) {
throw new Error("Invalid numeric values in date string.");
}
return new Date(year, month, day);
}
throw new Error(
"Unsupported input to parseLocalDate. Expected string or Date."
);
}
/**
* Format a JS Date object as a `yyyy-MM-dd` string (in local time).
* Useful for saving date-only data without time component.
*/
export function formatLocalDate(date: Date): string {
const year = date.getFullYear(); // ← local time
const month = `${date.getMonth() + 1}`.padStart(2, "0");
const day = `${date.getDate()}`.padStart(2, "0");
return `${year}-${month}-${day}`; // e.g. "2025-07-15"
}
/**
* Get a Date object representing midnight UTC for a given local date.
* Useful for comparing or storing dates consistently across timezones.
*/
export function toUTCDate(date: Date): Date {
return new Date(
Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())
);
}
/**
* Converts a stored UTC date string (e.g. from DB) into a Date object
* and formats it as local yyyy-MM-dd string for UI use.
*/
export function formatUTCDateStringToLocal(dateStr: string): string {
const localDate = parseLocalDate(dateStr); // will strip the time part
return formatLocalDate(localDate); // e.g., "2025-07-15"
}
/**
* Ensure any date (Date|string) is formatted to ISO string for consistent backend storage.
* If it's already a string, pass through. If it's a Date, convert to ISO.
*/
export function normalizeToISOString(date: Date | string): string {
const parsed = parseLocalDate(date);
return parsed.toISOString(); // ensures it always starts from local midnight
}
/**
* Formats a date string or Date object into a human-readable "DD Mon YYYY" string.
* Examples: "22 Jul 2025"
*
* @param dateInput The date as a string (e.g., ISO, YYYY-MM-DD) or a Date object.
* @returns A formatted date string.
*/
export const formatDateToHumanReadable = (dateInput: string | Date): string => {
// Create a Date object from the input.
// The Date constructor is quite flexible with various string formats.
const date = new Date(dateInput);
// Check if the date is valid. If new Date() fails to parse, it returns "Invalid Date".
if (isNaN(date.getTime())) {
console.error("Invalid date input provided:", dateInput);
return "Invalid Date"; // Or handle this error in a way that suits your UI
}
// Use Intl.DateTimeFormat for locale-aware, human-readable formatting.
return new Intl.DateTimeFormat("en-US", {
day: "2-digit", // e.g., "01", "22"
month: "short", // e.g., "Jan", "Jul"
year: "numeric", // e.g., "2023", "2025"
}).format(date);
};