cadrumo.core.time.clock module¶
Canonical wall-clock helpers for the AEAT domain.
A single, testable entry-point for obtaining the current UTC time.
Call-sites must import now() from this module rather than inlining
datetime.now(tz=UTC) directly, so the production clock can be traced
and call-sites stay uniform.
Deterministic-output seam¶
now() consults a context-variable frozen instant so a replay or
golden-capture scope can make every call site that routes through it
deterministic. The seam is DEFAULT-OFF: production never enters
frozen_clock(), so now() returns real
datetime.now(tz=UTC) with zero behaviour change. The seam is
context-var scoped — never process-global — so it cannot leak across
tasks the way freezegun / time_machine global freezing does, the
pattern banned in live-marked tests by the repo-root shared collection policy.
frozen_clock()
additionally refuses to activate while the pytest live-read opt-in
(cadrumo.core.config.Settings.live_tests_enabled) is set, keeping
live-marked tests on real wall-clock plus explicit clock= injection
exactly as today.
- now()[source]¶
Return the current UTC-aware datetime, or the frozen instant when the seam is active.
In production
_FROZEN_INSTANTis never set, so this returns real wall-clockdatetime.now(tz=UTC)with zero behaviour change. Under afrozen_clock()scope it returns the frozen instant, making every call site that routes through this function deterministic for the duration of the scope.- Return type:
- Returns:
A
datetime.datetimeinstance withdatetime.UTCas itstzinfo.
- MADRID_TZ¶
Spain’s peninsular civil timezone, the authority for regulated calendar boundaries.
Spanish tax calendar boundaries are governed by Spain’s official civil date, not the UTC date: filing plazos at the AEAT sede electrónica follow peninsular official time (Ley 39/2015 art. 31), and the IVA rate of an operation is the one in force at devengo (LIVA art. 90.Dos with art. 75) — a Spanish-calendar fact. The civil date leads UTC by one to two hours around midnight.
- today_madrid()[source]¶
Return the current civil date in Europe/Madrid, derived from the clock seam.
This is the authority a regulated date-boundary comparison defaults to (a filing plazo, an IVA rate-change date, a statutory-window year boundary) —
now()(UTC) reports yesterday’s Spanish date for up to two hours every night, selecting the wrong side of such a boundary in that window. Because it derives fromnow(),frozen_clock()pins it with zero new seam state; determinism is inherited, not re-engineered.Convention: a regulated or civil-date reference-date default reads
today_madrid(); a raw UTC calendar date (e.g. the date component of a UTC timestamp) readsnow().date(). The two are not interchangeable at the nightly boundary, so a reference date that legally binds to the Spanish calendar MUST usetoday_madrid().- Return type:
- Returns:
The current calendar
datetime.datein Europe/Madrid civil time.
- frozen_clock(instant)[source]¶
Freeze
now()toinstantfor the duration of the scope.This is the replay/golden-capture-only seam behind the deterministic-output substrate. It is DEFAULT-OFF (production never enters it) and context-var scoped (never process-global), and it refuses to activate under the pytest live-read opt-in.
- Parameters:
instant (
datetime) – The UTC-aware instantnow()returns while active.- Yields:
The frozen
instant.- Raises:
CoreValidationError – When
instantis naive or not UTC, or when the pytest live-read opt-in is enabled.- Return type: