Add date range helpers for day tabs
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { formatYyyymmdd, parseYyyymmdd, generateDateRange, findPageIndex } from "./dateRange.js";
|
||||
|
||||
describe("formatYyyymmdd", () => {
|
||||
it("formats a Date to yyyymmdd", () => {
|
||||
expect(formatYyyymmdd(new Date(2026, 3, 16))).toBe("20260416");
|
||||
});
|
||||
|
||||
it("pads single-digit month and day", () => {
|
||||
expect(formatYyyymmdd(new Date(2026, 0, 5))).toBe("20260105");
|
||||
});
|
||||
});
|
||||
|
||||
describe("parseYyyymmdd", () => {
|
||||
it("parses yyyymmdd into Date", () => {
|
||||
const d = parseYyyymmdd("20260416");
|
||||
expect(d.getFullYear()).toBe(2026);
|
||||
expect(d.getMonth()).toBe(3);
|
||||
expect(d.getDate()).toBe(16);
|
||||
});
|
||||
});
|
||||
|
||||
describe("generateDateRange", () => {
|
||||
it("generates dates from today-daysBefore to today+daysAfter inclusive", () => {
|
||||
const today = new Date(2026, 3, 16);
|
||||
const range = generateDateRange(today, 2, 3);
|
||||
expect(range).toHaveLength(6);
|
||||
expect(range[0]).toBe("20260414");
|
||||
expect(range[2]).toBe("20260416");
|
||||
expect(range[5]).toBe("20260419");
|
||||
});
|
||||
|
||||
it("handles zero-range", () => {
|
||||
const today = new Date(2026, 3, 16);
|
||||
expect(generateDateRange(today, 0, 0)).toEqual(["20260416"]);
|
||||
});
|
||||
|
||||
it("handles month boundaries", () => {
|
||||
const today = new Date(2026, 3, 1);
|
||||
const range = generateDateRange(today, 2, 0);
|
||||
expect(range).toEqual(["20260330", "20260331", "20260401"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findPageIndex", () => {
|
||||
it("finds page index for the given date at pageSize=7", () => {
|
||||
const dates = ["20260414", "20260415", "20260416", "20260417", "20260418", "20260419", "20260420", "20260421", "20260422"];
|
||||
expect(findPageIndex(dates, "20260414", 7)).toBe(0);
|
||||
expect(findPageIndex(dates, "20260420", 7)).toBe(0);
|
||||
expect(findPageIndex(dates, "20260421", 7)).toBe(1);
|
||||
expect(findPageIndex(dates, "20260422", 7)).toBe(1);
|
||||
});
|
||||
|
||||
it("returns 0 when date not found", () => {
|
||||
const dates = ["20260414", "20260415"];
|
||||
expect(findPageIndex(dates, "20260999", 7)).toBe(0);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Pure helper functions for generating and navigating date ranges
|
||||
* in the DayTabs component. No React, no side effects.
|
||||
*/
|
||||
|
||||
/** Format a Date as yyyymmdd (zero-padded). */
|
||||
export function formatYyyymmdd(d: Date): string {
|
||||
const y = d.getFullYear().toString();
|
||||
const m = (d.getMonth() + 1).toString().padStart(2, "0");
|
||||
const day = d.getDate().toString().padStart(2, "0");
|
||||
return `${y}${m}${day}`;
|
||||
}
|
||||
|
||||
/** Parse a yyyymmdd string into a local Date. */
|
||||
export function parseYyyymmdd(s: string): Date {
|
||||
const y = parseInt(s.slice(0, 4), 10);
|
||||
const m = parseInt(s.slice(4, 6), 10) - 1;
|
||||
const day = parseInt(s.slice(6, 8), 10);
|
||||
return new Date(y, m, day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an inclusive list of yyyymmdd strings spanning
|
||||
* [base - daysBefore, base + daysAfter].
|
||||
*/
|
||||
export function generateDateRange(base: Date, daysBefore: number, daysAfter: number): string[] {
|
||||
const result: string[] = [];
|
||||
for (let offset = -daysBefore; offset <= daysAfter; offset++) {
|
||||
const d = new Date(base.getFullYear(), base.getMonth(), base.getDate() + offset);
|
||||
result.push(formatYyyymmdd(d));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the page index (0-based) containing the given date, paginated by pageSize.
|
||||
* Returns 0 if the date is not in the list.
|
||||
*/
|
||||
export function findPageIndex(dates: string[], target: string, pageSize: number): number {
|
||||
const idx = dates.indexOf(target);
|
||||
if (idx < 0) return 0;
|
||||
return Math.floor(idx / pageSize);
|
||||
}
|
||||
Reference in New Issue
Block a user