Files
adam-acs/app/utils/schedule_window.ts
T
Kevin L'Hereec f9e56c78b1 refactor: migrate all internal imports to package.json subpath aliases
- Add #domain, #protocol, #utils aliases to package.json imports map
- Replace all relative imports (./, ../, ../..) in app/ and
  database/mongo_migrations/ with the corresponding #alias imports,
  eliminating relative path traversal across the codebase
- Remove dead code: ConfigurationVersionModel.findByConfigurationIdentifier
  (unused, superseded by paginateVersions) and unused exception classes
  (NotFoundException, UnprocessableEntityException, DatabaseException)
  from app/exceptions/index.ts, keeping only BadRequestException
- Fix pre-existing syntax error in configuration_version.ts (mismatched
  parenthesis) that broke tsc
- Fix eqeqeq violation in configuration_service.ts and isNaN ->
  Number.isNaN in configuration_engine.ts / cwmp-1-0.ts / exchange_controller.ts
- Fix no-shadow violation in cwmp-1-0.ts EventStruct constructor
- Prettier formatting pass on touched files

Validated: tsc --noEmit clean, eslint app/ clean, full test suite green.
2026-07-22 11:45:14 +02:00

85 lines
2.3 KiB
TypeScript

import type { ScheduleWindow } from '#domain/configuration/configuration'
/**
* Checks if the current time (or provided time) falls within the schedule window.
* Returns true if no schedule is defined (no restriction).
*
* Handles:
* - IANA timezone conversion (uses the timezone to get local hour and day)
* - Midnight-spanning windows (startHour > endHour means spans midnight)
* - Day-of-week filtering (daysOfWeek array, 0=Sunday)
*/
export function isWithinSchedule(schedule: ScheduleWindow | undefined, now?: Date): boolean {
if (!schedule) {
return true
}
const currentTime = now ?? new Date()
// Get the local hour and day in the schedule's timezone
const localParts = getLocalTimeParts(currentTime, schedule.timezone)
const localHour = localParts.hour
const localDay = localParts.dayOfWeek // 0=Sunday
// Check day-of-week filter
if (schedule.daysOfWeek.length > 0 && !schedule.daysOfWeek.includes(localDay)) {
return false
}
// Check time window
const { startHour, endHour } = schedule
if (startHour <= endHour) {
// Normal window (e.g., 2-6 means 02:00 to 06:00)
return localHour >= startHour && localHour < endHour
} else {
// Midnight-spanning window (e.g., 22-6 means 22:00 to 06:00 next day)
return localHour >= startHour || localHour < endHour
}
}
/**
* Gets the local hour and day-of-week for a given Date in a specific IANA timezone.
*/
function getLocalTimeParts(date: Date, timezone: string): { hour: number; dayOfWeek: number } {
const formatter = new Intl.DateTimeFormat('en-US', {
timeZone: timezone,
hour: 'numeric',
weekday: 'short',
hour12: false,
})
const parts = formatter.formatToParts(date)
let hour = 0
let dayOfWeek = 0
for (const part of parts) {
if (part.type === 'hour') {
// Intl may return "24" for midnight in some locales, normalize to 0
hour = Number.parseInt(part.value, 10) % 24
}
if (part.type === 'weekday') {
dayOfWeek = weekdayToNumber(part.value)
}
}
return { hour, dayOfWeek }
}
/**
* Converts a short weekday name (from Intl) to a number (0=Sunday).
*/
function weekdayToNumber(weekday: string): number {
const map: Record<string, number> = {
Sun: 0,
Mon: 1,
Tue: 2,
Wed: 3,
Thu: 4,
Fri: 5,
Sat: 6,
}
return map[weekday] ?? 0
}