Files
papercrate/frontend/src/utils/date.ts
T
2025-11-15 04:11:22 +01:00

64 lines
1.9 KiB
TypeScript

const ensureDate = (value: string | number | Date | null): Date | null => {
if (!value) {
return null;
}
const date = value instanceof Date ? new Date(value.getTime()) : new Date(value);
return Number.isNaN(date.getTime()) ? null : date;
};
interface FormatOptions {
fallback?: string;
locale?: Intl.LocalesArgument;
options?: Intl.DateTimeFormatOptions;
}
export const formatDate = (value: string | number | Date | null, { fallback = '—', locale, options }: FormatOptions = {}): string => {
const date = ensureDate(value);
if (!date) {
return fallback;
}
return date.toLocaleDateString(locale, options);
};
export const formatDateTime = (value: string | number | Date | null, { fallback = '—', locale, options }: FormatOptions = {}): string => {
const date = ensureDate(value);
if (!date) {
return fallback;
}
return date.toLocaleString(locale, options);
};
export const toDateInputValue = (value: string | number | Date | null): string => {
const date = ensureDate(value);
if (!date) {
return '';
}
const timezoneOffset = date.getTimezoneOffset();
const localDate = new Date(date.getTime() - timezoneOffset * 60000);
return localDate.toISOString().slice(0, 10);
};
export const toIssuedTimestamp = (dateString: string | null, fallback: string | number | Date | null): string | null => {
if (!dateString) {
return null;
}
const base = ensureDate(fallback) || new Date();
const [year, month, day] = dateString.split('-').map((part) => Number.parseInt(part, 10));
if (!year || !month || !day) {
return null;
}
const candidate = new Date(base);
candidate.setUTCFullYear(year, month - 1, day);
return Number.isNaN(candidate.getTime()) ? null : candidate.toISOString();
};
export const parseDateValue = (value: string | number | Date | null): Date | null => ensureDate(value);
export default {
formatDate,
formatDateTime,
toDateInputValue,
toIssuedTimestamp,
parseDateValue,
};