import type { ValueObject } from '@core/shared/domain/ValueObject'; import { RacingDomainValidationError } from '../errors/RacingDomainError'; export interface RaceTimeOfDayProps { hour: number; minute: number; } export class RaceTimeOfDay implements ValueObject { readonly hour: number; readonly minute: number; constructor(hour: number, minute: number) { if (!Number.isInteger(hour) || hour < 0 || hour > 23) { throw new RacingDomainValidationError(`RaceTimeOfDay hour must be between 0 and 23, got ${hour}`); } if (!Number.isInteger(minute) || minute < 0 || minute > 59) { throw new RacingDomainValidationError(`RaceTimeOfDay minute must be between 0 and 59, got ${minute}`); } this.hour = hour; this.minute = minute; } static fromString(value: string): RaceTimeOfDay { const match = /^(\d{2}):(\d{2})$/.exec(value); if (!match) { throw new RacingDomainValidationError(`RaceTimeOfDay string must be in HH:MM 24h format, got "${value}"`); } const hour = Number(match[1]); const minute = Number(match[2]); return new RaceTimeOfDay(hour, minute); } get props(): RaceTimeOfDayProps { return { hour: this.hour, minute: this.minute, }; } toString(): string { const hh = this.hour.toString().padStart(2, '0'); const mm = this.minute.toString().padStart(2, '0'); return `${hh}:${mm}`; } equals(other: ValueObject): boolean { const a = this.props; const b = other.props; return a.hour === b.hour && a.minute === b.minute; } }