55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import { RacingDomainValidationError } from '../errors/RacingDomainError';
|
|
import type { IValueObject } from '@core/shared/domain';
|
|
|
|
export interface RaceTimeOfDayProps {
|
|
hour: number;
|
|
minute: number;
|
|
}
|
|
|
|
export class RaceTimeOfDay implements IValueObject<RaceTimeOfDayProps> {
|
|
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: IValueObject<RaceTimeOfDayProps>): boolean {
|
|
const a = this.props;
|
|
const b = other.props;
|
|
return a.hour === b.hour && a.minute === b.minute;
|
|
}
|
|
} |