2025-05-09 10:45:32 +00:00
|
|
|
import { Result } from "@repo/rdx-utils";
|
2025-06-24 18:38:57 +00:00
|
|
|
import * as z from "zod/v4";
|
2025-09-16 11:29:45 +00:00
|
|
|
import { translateZodValidationError } from "../helpers";
|
2025-02-25 17:27:07 +00:00
|
|
|
import { ValueObject } from "./value-object";
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
interface UtcDateProps {
|
2025-02-25 17:27:07 +00:00
|
|
|
value: string;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
export class UtcDate extends ValueObject<UtcDateProps> {
|
2025-02-25 17:27:07 +00:00
|
|
|
private readonly date!: Date;
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
private constructor(props: UtcDateProps) {
|
2025-02-25 17:27:07 +00:00
|
|
|
super(props);
|
|
|
|
|
const { value: dateString } = props;
|
|
|
|
|
this.date = Object.freeze(new Date(dateString));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static validate(dateString: string) {
|
|
|
|
|
const dateStr = z.union([
|
|
|
|
|
z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/, "Invalid ISO 8601 format"),
|
|
|
|
|
z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Invalid YYYY-MM-DD format"),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
const dateStrToDate = dateStr.pipe(z.coerce.date());
|
|
|
|
|
|
|
|
|
|
return dateStrToDate.safeParse(dateString);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-04-01 15:32:53 +00:00
|
|
|
* Crea una instancia de UtcDate a partir de un string en formato UTC ISO 8601.
|
2025-06-24 18:38:57 +00:00
|
|
|
* @param isoDateString Fecha en formato UTC (con o sin hora YYYY-MM-DD)
|
2025-02-25 17:27:07 +00:00
|
|
|
* @returns UtcDate si es válida, Error en caso contrario.
|
|
|
|
|
*/
|
2025-06-24 18:38:57 +00:00
|
|
|
static createFromISO(isoDateString: string): Result<UtcDate, Error> {
|
|
|
|
|
const dateIsValid = UtcDate.validate(isoDateString);
|
2025-09-16 11:29:45 +00:00
|
|
|
|
2025-02-25 17:27:07 +00:00
|
|
|
if (!dateIsValid.success) {
|
2025-09-16 11:29:45 +00:00
|
|
|
return Result.fail(translateZodValidationError("UtcDate creation failed", dateIsValid.error));
|
2025-02-25 17:27:07 +00:00
|
|
|
}
|
|
|
|
|
|
2025-06-24 18:38:57 +00:00
|
|
|
return Result.ok(new UtcDate({ value: isoDateString }));
|
2025-02-25 17:27:07 +00:00
|
|
|
}
|
|
|
|
|
|
2025-09-04 10:02:24 +00:00
|
|
|
getProps(): string {
|
2025-02-25 17:27:07 +00:00
|
|
|
return this.props.value;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-01 14:26:15 +00:00
|
|
|
/**
|
2025-04-01 15:32:53 +00:00
|
|
|
* Devuelve la fecha completa en formato UTC con hora (ISO 8601). Ejemplo: 2025-12-31T23:59:59Z.
|
2025-04-01 14:26:15 +00:00
|
|
|
*/
|
|
|
|
|
toPrimitive() {
|
2025-04-01 15:32:53 +00:00
|
|
|
return this.toISOString();
|
2025-04-01 14:26:15 +00:00
|
|
|
}
|
|
|
|
|
|
2025-02-25 17:27:07 +00:00
|
|
|
/**
|
|
|
|
|
* Devuelve la fecha en formato UTC sin hora (YYYY-MM-DD).
|
|
|
|
|
*/
|
|
|
|
|
toDateString(): string {
|
|
|
|
|
return this.date.toISOString().split("T")[0];
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 18:14:19 +00:00
|
|
|
toString() {
|
|
|
|
|
return this.toDateString();
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-25 17:27:07 +00:00
|
|
|
/**
|
2025-04-01 15:32:53 +00:00
|
|
|
* Devuelve la fecha en formato UTC con hora (ISO 8601). Ejemplo: 2025-12-31T23:59:59Z.
|
2025-02-25 17:27:07 +00:00
|
|
|
*/
|
|
|
|
|
toISOString(): string {
|
|
|
|
|
return this.date.toISOString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Compara si dos instancias de UtcDate son iguales.
|
|
|
|
|
*/
|
|
|
|
|
equals(other: UtcDate): boolean {
|
|
|
|
|
return this.toISOString() === other.toISOString();
|
|
|
|
|
}
|
|
|
|
|
}
|