2.9 KiB
calendar-grid
Purpose
calendar-grid provides getCalendarMonth, which builds a full calendar month grid for use in UI calendar components and scheduling displays. It returns a CalendarMonth value containing one CalendarDay entry per day in the month, each annotated with its day-of-week index, whether it is a weekend, and whether it represents today (driven by an injectable Clock).
The module is intentionally narrow: it answers "what are the days in this month and which one is today?" — layout concerns (week rows, leading/trailing days from adjacent months) are left to the consumer.
Features
getCalendarMonth— builds aCalendarMonthgrid for a given year and 1-indexed month- Each
CalendarDayincludesdate,dayOfWeek(0=Sun … 6=Sat),isWeekend, andisToday - Injectable
Clockfor deterministic rendering in tests and server-side snapshots - Zero side effects; all computation is local
Usage: Basic Example
import { getCalendarMonth } from "@suaveplan/datetime";
const march = getCalendarMonth(2024, 3);
console.log(march.days.length); // 31
console.log(march.days[0]?.dayOfWeek); // 5 (Friday — Mar 1 2024)
const weekends = march.days.filter((d) => d.isWeekend);
console.log(weekends.length); // 10
Usage: Advanced Example
import { getCalendarMonth } from "@suaveplan/datetime";
// Deterministic "today" for SSR or snapshot tests
const fakeClock = () => new Date(2024, 2, 15).getTime(); // Mar 15 2024
const march = getCalendarMonth(2024, 3, { clock: fakeClock });
const today = march.days.find((d) => d.isToday);
console.log(today?.date.getDate()); // 15
// Render a simple ASCII calendar header
for (const day of march.days) {
const marker = day.isToday ? "*" : day.isWeekend ? "W" : " ";
process.stdout.write(`${marker}${String(day.date.getDate()).padStart(2)} `);
if (day.dayOfWeek === 6) process.stdout.write("\n");
}
API Reference
CalendarMonthOptions
interface CalendarMonthOptions {
clock?: Clock;
}
clock— injectableClock(returns epoch ms). Defaults toDate.now.
getCalendarMonth(year: number, month: number, opts?: CalendarMonthOptions): CalendarMonth
Build a CalendarMonth for the given year and 1-indexed month.
Params:
year— full calendar year (e.g. 2024)month— 1-indexed month (1 = January, 12 = December)opts.clock— optional injectable clock
Returns: { year, month, days: CalendarDay[] } where each CalendarDay is:
{ date: Date; dayOfWeek: Weekday; isWeekend: boolean; isToday: boolean }
Implementation Notes
isToday is computed by comparing a "year-month-date" string derived from clock() to the same string for each grid day. This string comparison avoids UTC/local timezone confusion that would arise from comparing epoch timestamps directly. The clock default (Date.now) is captured once per call to ensure consistent "today" across all days in the grid.