Files
feishin/src/shared/api/partial-iso-date.ts
T
2026-04-02 19:39:08 -07:00

47 lines
1.3 KiB
TypeScript

const PARTIAL_ISO = /^\d{4}(-\d{2}(-\d{2})?)?$/;
export const coerceYear = (value: null | number | undefined): number => {
if (typeof value !== 'number' || !Number.isFinite(value)) {
return 0;
}
return value;
};
// Parses `YYYY`, `YYYY-MM`, or `YYYY-MM-DD`. Returns the trimmed string as `date` when valid.
export const parsePartialIsoDate = (
input: null | string | undefined,
): { date: null | string; year: number } => {
if (input == null || typeof input !== 'string') {
return { date: null, year: 0 };
}
const s = input.trim();
if (!s || !PARTIAL_ISO.test(s)) {
return { date: null, year: 0 };
}
const year = Number.parseInt(s.slice(0, 4), 10);
if (!Number.isFinite(year)) {
return { date: null, year: 0 };
}
return { date: s, year };
};
// Like `parsePartialIsoDate`, but if the value is a full ISO datetime, uses the `YYYY-MM-DD` prefix.
export const parsePartialIsoDateFromApi = (
input: null | string | undefined,
): { date: null | string; year: number } => {
const direct = parsePartialIsoDate(input);
if (direct.date) {
return direct;
}
if (input != null && typeof input === 'string' && input.length >= 10) {
return parsePartialIsoDate(input.slice(0, 10));
}
return { date: null, year: 0 };
};