50 lines
1.4 KiB
TypeScript
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 };
|