Files
SixFlagsSuperCalendar/lib/env.ts
josh fbf4337a83
All checks were successful
Build and Deploy / Build & Push (push) Successful in 5m54s
feat: park page operating window check; always show ride total
- 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>
2026-04-04 20:43:33 -04:00

60 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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;
}