54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import type { Race } from "../api";
|
||
|
||
export const WEEKDAY_LABELS_SHORT_RU: string[] = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"];
|
||
|
||
/** Monday-based week: Mon=0 ... Sun=6 */
|
||
function mondayIndexFromJsDay(jsDay: number): number {
|
||
return (jsDay + 6) % 7;
|
||
}
|
||
|
||
/** Monday-based week: Mon=0 ... Sun=6 */
|
||
export function mondayIndexFromDate(d: Date): number {
|
||
return mondayIndexFromJsDay(d.getDay());
|
||
}
|
||
|
||
/** Grid cells for one month: `null` = empty, `1..31` = day of month. Padded to full weeks, at least 6 rows. */
|
||
export function buildMonthCells(year: number, monthIndex: number): (number | null)[] {
|
||
const lead = mondayIndexFromJsDay(new Date(Date.UTC(year, monthIndex, 1)).getUTCDay());
|
||
const dim = new Date(Date.UTC(year, monthIndex + 1, 0)).getUTCDate();
|
||
const cells: (number | null)[] = [];
|
||
for (let i = 0; i < lead; i += 1) {
|
||
cells.push(null);
|
||
}
|
||
for (let day = 1; day <= dim; day += 1) {
|
||
cells.push(day);
|
||
}
|
||
while (cells.length % 7 !== 0) {
|
||
cells.push(null);
|
||
}
|
||
while (cells.length < 42) {
|
||
cells.push(null);
|
||
}
|
||
return cells;
|
||
}
|
||
|
||
export function toYmd(year: number, monthIndex: number, day: number): string {
|
||
const m = String(monthIndex + 1).padStart(2, "0");
|
||
const d = String(day).padStart(2, "0");
|
||
return `${year}-${m}-${d}`;
|
||
}
|
||
|
||
export function groupRacesByYmd(races: Race[]): Map<string, Race[]> {
|
||
const map = new Map<string, Race[]>();
|
||
for (const race of races) {
|
||
const ymd = race.date.slice(0, 10);
|
||
if (!/^\d{4}-\d{2}-\d{2}$/.test(ymd)) {
|
||
continue;
|
||
}
|
||
const list = map.get(ymd) ?? [];
|
||
list.push(race);
|
||
map.set(ymd, list);
|
||
}
|
||
return map;
|
||
}
|