Files
Jyotisha/frontend/src/lib/rectification-agentic/date-range.ts
T
Jesse_Chen f3946eaa6f
Staging Backend Quality Gate / validate (push) Failing after 9m57s
Staging Backend Quality Gate / publish (push) Has been skipped
chore: retire legacy rectification runtime
2026-08-07 12:55:32 +08:00

54 lines
1.9 KiB
TypeScript

export type AgenticRectificationDatePrecision = "day" | "month" | "quarter" | "year";
export type AgenticRectificationDateRange = Readonly<{
start: string;
end: string;
precision: AgenticRectificationDatePrecision;
label: string;
}>;
function isoDate(year: number, month: number, day: number): string {
const value = new Date(Date.UTC(year, month - 1, day));
if (value.getUTCFullYear() !== year || value.getUTCMonth() !== month - 1 || value.getUTCDate() !== day) {
throw new Error("invalid_calendar_date");
}
return value.toISOString().slice(0, 10);
}
function monthEnd(year: number, month: number): string {
return new Date(Date.UTC(year, month, 0)).toISOString().slice(0, 10);
}
export function dateRangeFromDeclared(
value: string,
precision: AgenticRectificationDatePrecision,
): AgenticRectificationDateRange {
if (precision === "day") {
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) throw new Error("invalid_day");
const [year, month, day] = value.split("-").map(Number);
const date = isoDate(year!, month!, day!);
return { start: date, end: date, precision, label: value };
}
if (precision === "month") {
if (!/^\d{4}-\d{2}$/.test(value)) throw new Error("invalid_month");
const [year, month] = value.split("-").map(Number);
const start = isoDate(year!, month!, 1);
return { start, end: monthEnd(year!, month!), precision, label: value };
}
if (precision === "quarter") {
const matched = /^(\d{4})-Q([1-4])$/.exec(value);
if (!matched) throw new Error("invalid_quarter");
const year = Number(matched[1]);
const firstMonth = (Number(matched[2]) - 1) * 3 + 1;
return {
start: isoDate(year, firstMonth, 1),
end: monthEnd(year, firstMonth + 2),
precision,
label: value,
};
}
if (!/^\d{4}$/.test(value)) throw new Error("invalid_year");
const year = Number(value);
return { start: isoDate(year, 1, 1), end: isoDate(year, 12, 31), precision, label: value };
}