Files
frontend/src/shared/lib/calendar.ts
T
ksv741 612ab62509
Frontend verify / commits (pull_request) Successful in 50s
Frontend verify / security (pull_request) Successful in 10s
Frontend verify / verify (pull_request) Successful in 7m7s
fix(events): seven-date default period and picker from today (WealthLedger/frontend#63)
2026-10-14 21:22:09 +03:00

50 lines
1.4 KiB
TypeScript

import { calendarDate } from "./calendar.schema";
function isValidPeriod(from: null | string, to: null | string) {
return (
[from, to].every(
date => date === null || calendarDate.safeParse(date).success,
)
&& (!from || !to || from <= to)
);
}
const DEFAULT_PERIOD_LAST_INDEX = 6;
const moscowFormatter = new Intl.DateTimeFormat("en-CA", {
day: "2-digit",
month: "2-digit",
timeZone: "Europe/Moscow",
year: "numeric",
});
// Newest first. Missing dates sort last in both directions, so a row without a
// date never jumps to the top of a "past" list.
function compareDateDesc(a: null | string, b: null | string) {
return (b ?? "").localeCompare(a ?? "");
}
// 7 calendar dates starting with today (Moscow calendar arithmetic).
function defaultPeriod(): [string, string] {
const from = moscowDate(new Date());
const [year = 1970, month = 0, day = 1] = from.split("-").map(Number);
const noon = 12;
const lastDay = day + DEFAULT_PERIOD_LAST_INDEX;
const end = new Date(Date.UTC(year, month - 1, lastDay, noon));
const to = moscowDate(end);
return [from, to];
}
function moscowDate(value: Date): string {
const parts = moscowFormatter.formatToParts(value);
const part = (type: string) =>
parts.find(item => item.type === type)?.value;
return `${part("year")}-${part("month")}-${part("day")}`;
}
export { compareDateDesc, defaultPeriod, isValidPeriod, moscowDate };