All checks were successful
Build and Deploy / Build & Push (push) Successful in 5m54s
- Extract isWithinOperatingWindow() to lib/env.ts (shared) - Park detail page: always fetch Queue-Times, but force all rides closed when outside the ±1h operating window - LiveRidePanel: always show closed ride count badge (not just when some rides are also open); label reads "X rides total" when none are open vs "X closed / down" when some are Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
60 lines
2.3 KiB
TypeScript
60 lines
2.3 KiB
TypeScript
/**
|
||
* Environment variable helpers.
|
||
*/
|
||
|
||
/**
|
||
* Parse a staleness window from an env var string (interpreted as hours).
|
||
* Falls back to `defaultHours` when the value is missing, non-numeric,
|
||
* non-finite, or <= 0 — preventing NaN from silently breaking staleness checks.
|
||
*/
|
||
export function parseStalenessHours(envVar: string | undefined, defaultHours: number): number {
|
||
const parsed = parseInt(envVar ?? "", 10);
|
||
return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultHours;
|
||
}
|
||
|
||
/**
|
||
* Returns today's date as YYYY-MM-DD using local wall-clock time with a 3 AM
|
||
* switchover. Before 3 AM local time we still consider it "yesterday", so the
|
||
* calendar doesn't flip to the next day at midnight while people are still out
|
||
* at the park.
|
||
*
|
||
* Important: `new Date().toISOString()` returns UTC, which causes the date to
|
||
* advance at 8 PM EDT (UTC-4) or 7 PM EST (UTC-5) — too early. This helper
|
||
* corrects that by using local year/month/day components and rolling back one
|
||
* day when the local hour is before 3.
|
||
*/
|
||
export function getTodayLocal(): string {
|
||
const now = new Date();
|
||
if (now.getHours() < 3) {
|
||
now.setDate(now.getDate() - 1);
|
||
}
|
||
const y = now.getFullYear();
|
||
const m = String(now.getMonth() + 1).padStart(2, "0");
|
||
const d = String(now.getDate()).padStart(2, "0");
|
||
return `${y}-${m}-${d}`;
|
||
}
|
||
|
||
/**
|
||
* Returns true when the current local time is within 1 hour before open
|
||
* or 1 hour after close, based on a hoursLabel like "10am – 6pm".
|
||
* Falls back to true when the label can't be parsed.
|
||
*/
|
||
export function isWithinOperatingWindow(hoursLabel: string): boolean {
|
||
const m = hoursLabel.match(
|
||
/^(\d+)(?::(\d+))?(am|pm)\s*[–-]\s*(\d+)(?::(\d+))?(am|pm)$/i
|
||
);
|
||
if (!m) return true;
|
||
const toMinutes = (h: string, min: string | undefined, period: string) => {
|
||
let hours = parseInt(h, 10);
|
||
const minutes = min ? parseInt(min, 10) : 0;
|
||
if (period.toLowerCase() === "pm" && hours !== 12) hours += 12;
|
||
if (period.toLowerCase() === "am" && hours === 12) hours = 0;
|
||
return hours * 60 + minutes;
|
||
};
|
||
const openMin = toMinutes(m[1], m[2], m[3]);
|
||
const closeMin = toMinutes(m[4], m[5], m[6]);
|
||
const now = new Date();
|
||
const nowMin = now.getHours() * 60 + now.getMinutes();
|
||
return nowMin >= openMin - 60 && nowMin <= closeMin + 60;
|
||
}
|