FHIR defines four temporal datatypes and integrations that treat them interchangeably ship subtle bugs. date, dateTime, instant, and time each have specific precision and timezone rules, and using the wrong one produces payloads that validate loosely and behave oddly. The site's FHIR timestamp inspector tells you which datatype you have and what its precision means. For the wider setting, the FHIR implementation reference has more.
The Four Types
date— year, year-month, or year-month-day; no time, no timezonedateTime— date plus optional time; if time is present, timezone is required at second precision or betterinstant— always full precision with timezone; used for machine timestampstime— hours:minutes:seconds with optional fractional seconds; no date, no timezone
Each is a real distinction. Pick the right one for the meaning your data carries.
When To Use date
Birthdays. Anniversaries. Any calendar-scale event where a specific instant is meaningless.
Patient.birthDate uses date because "born on July 4" is a fact independent of the time of day. For the partial-date case, partial dates: birthDate is not always a full date is the entry.
When To Use dateTime
Encounters, observations, procedures — anything where the time might matter but the precision varies.
Observation.effectiveDateTime uses dateTime. It can be 2026-07-11 (just a date), 2026-07-11T14:00:00-05:00 (with time), or anywhere in between. That flexibility matches how clinical timing actually gets recorded.
For the timezone side, timezones in clinical timestamps and where they hide is the entry.
When To Use instant
Machine-generated timestamps. Audit events. meta.lastUpdated. Any place where the exact moment is what matters and precision is not variable.
instant always carries second-or-better precision and a timezone. AuditEvent.recorded uses instant.
When To Use time
Rare in clinical resources. Times of day without a date — office hours, scheduled reminders. Not for actual event timestamps.
The Precision Question
- date: year, year-month, or year-month-day
- dateTime: any precision from year to milliseconds; timezone required if time present at second precision or better
- instant: always second-or-better with milliseconds optional; timezone required
- time: hours:minutes:seconds with optional milliseconds
Sending an instant with only date precision fails validation. Sending a dateTime with time but no timezone fails validation. The inspector flags each violation.
The Timezone Rule
Timezones are required at second precision or better for dateTime and instant. UTC is Z. Offsets are +HH:MM or -HH:MM.
Missing timezone at second precision is a spec violation. Some servers accept it and interpret in server-local time; that produces subtle bugs when clients and servers are in different zones.
The Common Mistakes
- Storing a birthDate as a full instant (over-precise, timezone dishonest)
- Storing an AuditEvent time as a date (loses the moment)
- Storing effectiveDateTime with time but no timezone (spec violation)
- Formatting a partial date as a full date in the UI (implies precision that is not there)
For the UI-formatting case, formatting a FHIR dateTime for a UI without lying about precision is the entry.
The Short Version
date for calendar events. dateTime for variable-precision clinical timing. instant for machine timestamps. time for times-of-day without dates. Timezones required at second precision or better. The inspector tells you which type you have and what precision your value carries.

Sources
- HL7 canonical R4 datatypes chapter covering date - HL7 canonical R4 datatypes chapter covering date, dateTime, instant, time
