cadrumo.core.parsing.dates module

Date string parsers for the two distinct input formats used across AEAT adapters.

Provides a unified _parse_date() helper that combines format selection with an error-policy axis.

The two variants are intentionally separate because they accept different wire formats:

  • parse_iso8601_date() — YYYY-MM-DD (ISO 8601). Used wherever AEAT systems or profile storage serialises dates in the standard form (e.g. deadline-profile censo dates).

  • parse_ddmmyyyy_date() — DD-MM-YYYY or DD/MM/YYYY (day-first, separator is - or /). Used wherever the AEAT G313 (Mis Datos Censales) HTML page publishes dates in the Spanish day-first convention.

Both functions live at the core layer: they carry no domain dependencies, perform no I/O, and raise ValueError so callers can wrap the error in the domain-appropriate exception type.

parse_iso8601_date(raw)[source]

Parse an ISO-8601 date string (YYYY-MM-DD) into a date.

Parameters:

raw (str | None) – Raw string from a profile or registry field. None and empty strings are treated as absent and return None.

Return type:

date | None

Returns:

Parsed datetime.date, or None when raw is absent.

Raises:

ValueError – When raw is non-empty but does not conform to ISO-8601. Callers are expected to wrap this in the appropriate domain exception.

require_iso8601_date(raw)[source]

Parse a required extended-form ISO-8601 date, refusing every other shape.

The strict counterpart of parse_iso8601_date() for values that must be present and must be a real calendar date. Absence is a refusal rather than None, and the compact YYYYMMDD form fromisoformat() also accepts is refused, so the one admitted shape is the extended YYYY-MM-DD the AEAT wire formats use.

A model that declares a date as a length-bounded string admits an impossible calendar date – 2026-99-99 and 2026-02-30 are both ten characters – and every consumer downstream of it inherits that value as if a date authority had approved it.

Parameters:

raw (str) – The declared date string.

Return type:

date

Returns:

The parsed calendar date.

Raises:

ValueError – When raw is absent, is not extended-form YYYY-MM-DD, or names a date that does not exist. Callers wrap this in the domain-appropriate exception; inside a pydantic validator it propagates into the ValidationError chain.

parse_ddmmyyyy_date(raw)[source]

Parse a Spanish day-first date string (DD-MM-YYYY / DD/MM/YYYY).

Both separator characters (- and /) are accepted because the AEAT G313 page uses them interchangeably across form revisions.

Parameters:

raw (str | None) – Raw string scraped from a G313 HTML field. None and empty strings are treated as absent and return None.

Return type:

date | None

Returns:

Parsed datetime.date, or None when raw is absent.

Raises:

ValueError – When raw is non-empty but does not match the expected format or represents an invalid calendar date. Callers are expected to wrap this in the appropriate domain exception.

parse_date(raw, *, fmt='iso8601', on_error='raise')

Public alias — cross-package callers must import parse_date rather than the private _parse_date implementation name.

Return type:

date | None

Parameters:
  • raw (str | None)

  • fmt (Literal['iso8601', 'ddmmyyyy'])

  • on_error (Literal['raise', 'none'])