Skip to content

Dates and time

Open Meridian keeps two kinds of time apart, because they answer different questions:

  • a moment: an instant, in nanoseconds since the Unix epoch, in UTC. When a trade printed, when a row was recorded, when a price was in force. Every field ending _ns is one.
  • a date: a plain calendar day, with no time and no zone. Which business day a close is for, the date positions are read at. It crosses the wire as its ISO 8601 text, 2026-10-09.

A daily price is keyed by a date

A close, a NAV, a settlement price or a daily bar is for a business date, and is keyed by it: the close of 2026-10-08, not a moment that happens to fall on it in some zone. Real-time data, a last price or a bid, is keyed by the moments it was in force, the venue's zone known from its venue.

Trades and quotes name no business date. A trade is valid from its event time at its venue, a quote from its time until the next for the same subject, dataset, venue and asset, and the lake refuses either naming a business date. A range read of them lies within one day of each dataset, as the dataset declares its day below, never "one business day" by a calendar; a wider range is refused, naming the range.

A dataset's day

Which candle or session counts as a business date depends on the dataset, so each dataset declares its day:

Declared What it says For example
day_time_zone The IANA zone a business date is in. Empty for a dataset that is not daily. America/New_York for a US close and FX's 17:00 roll; Etc/UTC for a crypto venue's daily candle.
day_end_minute The minutes after local midnight the day ends, 0 to 1,439; 0 ends it at midnight. 960 for a US equity close at 16:00 New York; 1,020 for FX at 17:00 New York; 0 for a candle ending at UTC midnight.
calendar_id The settlement calendar its business dates follow, by its CAL- ID; empty names none. Anything else is refused at registration, naming the field. The NYSE markets' trading calendar for a US equity close.

So the day says which session counts as the date, and when its value is final. It carries no holiday calendar: a business date with no session has no close. A dataset may name its calendar beside its day: a daily value dated on a day that calendar says is closed is still recorded as reported, and flagged with why the day is closed (see A daily value on a closed day and Settlement calendars).

A day still forming is recorded and restated as it fills: its row's valid time ends after the moment it is read, under one row key, until its close is final. A reader sees the latest version; a read as of an earlier moment sees the version in force then.

A date is checked at both ends

A date is a date in the SDK and in core, and text that is no date is refused, naming the field, before it goes anywhere:

  • In the SDK, every field the data dictionary types date takes a Python datetime.date, or its ISO text. Text that is no day that exists (2026-02-30), text in another form (20261009) and a datetime, which is a moment, are refused before anything is sent. What comes back is the text: date.fromisoformat(price.meta.business_date).
  • In core, the sidecar refuses a batch or a read naming a business date that is no day, before anything is sent on, and the lake and the book read every date as a date.

On the wire a date is its ISO text, so a plugin that builds its params by hand sends valid ISO dates.