Skip to main content
Decisions
DraftLast reviewed 2026-06-24

ADR-003: Business date and system time separation

Status​

Accepted

Context​

Financial systems operate with more than one meaningful time dimension. OpenTRMS needs to distinguish:

  • the operator-controlled business date used for EOD and daily processing
  • the wall-clock timestamp when the platform observed or wrote something
  • the trade execution timestamp supplied by an upstream caller

Collapsing those into a single now() value breaks late booking, historical replay, and bitemporal reasoning.

Decision​

OpenTRMS uses BusinessClock as the application boundary for time-sensitive logic. The platform keeps three separate concepts:

  • business_date from BusinessClock.businessDate()
  • system_timestamp() from BusinessClock.systemTimestamp()
  • trade_timestamp supplied by the caller and stored as received

Application code should not call LocalDate.now(), Instant.now(), or other direct system clock APIs for business behavior.

Consequences​

This decision makes EOD sequencing and historical replay reproducible. It also forces developers to be explicit about which notion of time they are using.

In practice:

  • business_date drives workflow and daily eligibility
  • system_timestamp() drives recorded_at, booked_at, and similar audit facts
  • trade_timestamp stays distinct from both, with trade_date derived from it

Projection and audit tables that participate in bitemporal reads may therefore carry both as_of_date and recorded_at, because those fields answer different questions.