← All writing2026.07.10 · COMMERCE · Commerce Systems in Production

Business Time: Consistent Boundaries for Orders and Reconciliation

Separate an instant from its business date, and use explicit period boundaries across reports, identifiers and scheduled work.

An order, a refund and a daily close can each use a different clock. If their period boundaries depend on the server or browser timezone, the same event can end up in different reports.

The platform uses an explicit business timezone for period calculations and operational dates. The important choice is to make this policy shared and testable. Examples below use UTC as an illustrative policy, not the client’s configuration.

Separate the instant from the business date

An event timestamp identifies when something happened. A business date determines which reporting period owns it. A formatted string controls what a reader sees.

I keep these responsibilities distinct:

Responsibility Representation
Event time A timestamp representing an instant
Reporting period Start and end instants computed for the business timezone
Operational display A clearly specified display timezone

PostgreSQL timestamptz represents an instant. Changing a session timezone changes its display, not when the event occurred. It does not retain the original input timezone as a separate business fact.

Query a half-open period

For daily close and other period-based decisions, compute the boundaries first and pass them to the query:

SELECT *
FROM business_events
WHERE occurred_at >= $1
  AND occurred_at < $2;

The interval includes its start and excludes its end. There is no need to invent the final millisecond of a day, and adjacent periods cannot overlap at their shared boundary.

An illustrative explicit grouping is:

SELECT (occurred_at AT TIME ZONE 'UTC')::date AS business_date,
       count(*)
FROM business_events
GROUP BY 1;

A bare cast from timestamptz to date instead inherits the session timezone. That is a hidden dependency for a report that runs in more than one environment.

Reconcile events that cross periods

A purchase and its refund may happen on different days. Reconciliation must include the later movement and the original transaction it refers to. Filtering only by the order’s creation date would miss the refund’s effect on today’s balances.

The implemented close checks use the business period to identify relevant movements, then compare them with their source records. Operational identifiers also use the same date policy, giving support and reconciliation a consistent reference.

Test the boundaries

The useful cases are immediately before and after a period boundary, a refund after the original order day, and execution under different process timezones. The expected business period should remain the same.

A timezone setting is an input to the model. Leaving it to whichever machine runs the query makes accounting periods an infrastructure side effect.