Date Search Precision and the Range It Implicitly Covers

Editorial illustration in vaporwave-pastel style depicting a date precision ladder from year to millisecond with prefix semantics and two-parameter range shape

FHIR date search has a precision-implies-range rule that trips up callers who have not read the chapter. A search for ?date=2026 matches everything in that year. A search for ?date=2026-07-11 matches everything on that day. The precision of the search value implicitly defines the range being queried. Getting that wrong produces queries that under-fetch or over-fetch by orders of magnitude. The site's FHIR search query auditor surfaces the implied range. For the wider FHIR framing, the FHIR engineering reference has more.

The Precision Rule

  • ?date=2026 matches everything in the year 2026
  • ?date=2026-07 matches everything in July 2026
  • ?date=2026-07-11 matches everything on July 11, 2026
  • ?date=2026-07-11T15:00Z matches everything at 15:00 UTC on that day
  • ?date=2026-07-11T15:00:00Z matches at the second level
  • ?date=2026-07-11T15:00:00.000Z matches at the millisecond level

Each level of precision defines the range being matched. The prefix decides whether that range is the target of equality, greater-than, less-than, or a bounding operator.

Prefixes Bind the Range Semantics

  • eq2026-07-11 matches values inside July 11
  • ne2026-07-11 matches values outside July 11
  • gt2026-07-11 matches values strictly after July 11 (after end-of-day)
  • lt2026-07-11 matches values strictly before July 11 (before start-of-day)
  • ge2026-07-11 matches values from start-of-day onwards
  • le2026-07-11 matches values through end-of-day
  • sa2026-07-11 matches values entirely after the range
  • eb2026-07-11 matches values entirely before the range
  • ap2026-07-11 approximate — implementation-defined

The default when no prefix is present is eq. Callers who write ?date=2026-07-11 expecting gt semantics get the equality range and are surprised by the count.

Timezone Ambiguity

2026-07-11 without a timezone is interpreted in the server's zone. Servers in different jurisdictions treat this differently. The safe pattern is to include a timezone marker (Z for UTC, or +HH:MM / -HH:MM for offsets) at second precision or better.

A client that reads UTC and writes queries in local time will silently shift results by up to a full day. That is a common source of "the report is missing one row" and the fix is usually a timezone marker on the query.

For the broader picture of quiet-wrong queries, the FHIR searches that look correct but are wrong covers the pattern.

Range Search Requires Two Parameters

To search for "between two dates" you send two parameters: ?date=ge2026-07-01&date=le2026-07-31. FHIR does not have a single-parameter range shorthand. Callers who invent one — ?date=2026-07-01..2026-07-31 — get a syntax the server does not understand and either an error or a silent fallback.

For the modifier semantics that also stack on date searches, modifier stacking: :not, :in, :missing without foot-guns covers the surface.

Auditor Behavior

The auditor at /dev-tools/audit-fhir-query/ calculates the implied range from precision plus prefix and displays it. That single readout removes most of the "surprise count" cases. For the broader linter rule set, linter rules to catch the ten most common search mistakes is the reference.

The Short Version

Precision defines the range, prefix binds the semantics, timezone belongs on the value. Range search takes two parameters. Every ambiguity in the query becomes a wrong result count.

Vaporwave-pastel diagram of a date-precision ladder from year down to millisecond, with each rung showing the implied search range, on a soft dusk-purple background

Sources