Files
flights_web/src/features/flights-map/calendarRange.ts
T

97 lines
2.7 KiB
TypeScript

/**
* Calendar helpers for the flights-map filter date picker.
*
* All dates are treated as date-only (time zero'd) for day-level comparisons.
* minDate/maxDate form the selectable window; `buildDisabledDates` produces
* the complement of `availableDays` over that window; `findNextEnabledDate`
* advances a current selection forward until it lands on an enabled day.
*
* Matches Angular `FlightsMapFiltersStateService` calendar behavior.
*/
/** Today with time set to 00:00:00 local. */
export function today(): Date {
const d = new Date();
d.setHours(0, 0, 0, 0);
return d;
}
/** minDate = today - 1 day (Angular parity). */
export function getMinDate(): Date {
const d = today();
d.setDate(d.getDate() - 1);
return d;
}
/** maxDate = today + 6 months (Angular parity). */
export function getMaxDate(): Date {
const d = today();
d.setMonth(d.getMonth() + 6);
return d;
}
/**
* Every date in [minDate, maxDate] whose yyyymmdd is NOT in `availableDays`.
* When `availableDays` is empty, every date in the range is disabled.
*/
export function buildDisabledDates(
minDate: Date,
maxDate: Date,
availableDays: ReadonlyArray<string>,
): Date[] {
const available = new Set(availableDays);
const disabled: Date[] = [];
const cursor = new Date(minDate);
cursor.setHours(0, 0, 0, 0);
const end = new Date(maxDate);
end.setHours(0, 0, 0, 0);
while (cursor.getTime() <= end.getTime()) {
const key = toYyyymmdd(cursor);
if (!available.has(key)) disabled.push(new Date(cursor));
cursor.setDate(cursor.getDate() + 1);
}
return disabled;
}
/**
* Advances `current` day-by-day until it hits a non-disabled date, staying
* within [minDate, maxDate]. Returns `null` if no enabled date exists.
* `current` itself is tested first. If `current < minDate`, starts at minDate.
*/
export function findNextEnabledDate(
current: Date,
disabledDates: ReadonlyArray<Date>,
minDate: Date,
maxDate: Date,
): Date | null {
const disabledSet = new Set(
disabledDates.map((d) => {
const x = new Date(d);
x.setHours(0, 0, 0, 0);
return x.getTime();
}),
);
const min = new Date(minDate);
min.setHours(0, 0, 0, 0);
const max = new Date(maxDate);
max.setHours(0, 0, 0, 0);
const cursor = new Date(current);
cursor.setHours(0, 0, 0, 0);
if (cursor.getTime() < min.getTime()) cursor.setTime(min.getTime());
while (cursor.getTime() <= max.getTime()) {
if (!disabledSet.has(cursor.getTime())) return new Date(cursor);
cursor.setDate(cursor.getDate() + 1);
}
return null;
}
function toYyyymmdd(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}`;
}