# HowTo: Der FHIR `date`-Suchparameter – Präfixe, Intervalle und Kombinationen richtig verstehen Wer FHIR-Server baut oder abfragt, stolpert früher oder später über den `date`-Suchparameter. Auf den ersten Blick sieht er simpel aus – `?date=2023-06-15` – aber sobald Präfixe wie `ge`, `sa` oder `ap` ins Spiel kommen und mehrere `date`-Parameter kombiniert werden, wird es schnell unübersichtlich. Dieser Artikel bringt Ordnung rein: Schritt für Schritt, mit Zeitleisten-Grafiken zu jedem Fall. --- ## 1. Das Grundprinzip: FHIR vergleicht Intervalle, keine Zeitpunkte Der wichtigste gedankliche Reset zuerst: FHIR behandelt Datumswerte nie als exakten Zeitpunkt, sondern immer als **Intervall**. Wie breit dieses Intervall ist, hängt von der Precision des angegebenen Werts ab: - `2023` → das ganze Jahr 2023 - `2023-06` → der ganze Juni 2023 - `2023-06-15` → der ganze 15. Juni 2023 (00:00–24:00 Uhr) - `2023-06-15T10:00:00` → (fast) ein exakter Zeitpunkt Jeder Vergleichsoperator vergleicht anschließend **zwei Intervalle** miteinander: das Such-Intervall aus deinem Query-Parameter und das Resource-Intervall aus dem Feld der Ressource (z. B. `Patient.birthDate` oder `Encounter.period`). ### Ohne Präfix = `eq`, aber die Precision entscheidet mit Gibst du kein Präfix an, nimmt der Server `eq` an. Das Resource-Datum muss dann **vollständig** innerhalb deines Such-Intervalls liegen. Je gröber die Precision, desto breiter das Intervall – und desto mehr Resource-Werte passen hinein: ![Datum ohne Präfix](fhir-date-ohne-praefix.svg) `date=2023-06-15` matched nur diesen einen Tag. `date=2023-06` matched dagegen jeden Tag im Juni – auch den 15. Das ist der häufigste Stolperstein für Einsteiger: eine „ungenaue" Suchanfrage ist nicht strenger, sondern lockerer. --- ## 2. Die neun Präfixe im Überblick FHIR definiert insgesamt neun Präfixe für `date`. Jeder davon beschreibt eine andere Beziehung zwischen Such-Intervall (rot gestrichelt in der Grafik) und Treffer-Bereich (grün/farbig schattiert): ![Alle Präfixe](fhir-date-alle-praefixe.svg) | Präfix | Name | Bedeutung | |---|---|---| | `eq` | gleich | Resource-Intervall liegt vollständig im Such-Intervall | | `ne` | ungleich | Komplement von `eq` | | `gt` | größer als | Resource-Datum beginnt nach dem Ende des Such-Intervalls | | `lt` | kleiner als | Resource-Datum endet vor dem Beginn des Such-Intervalls | | `ge` | größer/gleich | Beginnt am oder nach Beginn des Such-Intervalls | | `le` | kleiner/gleich | Endet am oder vor Ende des Such-Intervalls | | `sa` | starts after | Beginnt vollständig **nach** dem Ende des Such-Intervalls | | `eb` | ends before | Endet vollständig **vor** dem Beginn des Such-Intervalls | | `ap` | approximately | Ungefähre Übereinstimmung, Toleranz serverabhängig | **Praxis-Tipp:** `sa`/`eb` unterscheiden sich von `gt`/`lt` nur spürbar bei Resource-Feldern, die selbst ein **Intervall** sind (`Period`, z. B. `Encounter.period`). Bei einem einzelnen Zeitpunkt-Feld ist der Unterschied meist nicht beobachtbar – `gt` reicht schon, wenn die Period *beginnt* nach dem Suchdatum; `sa` verlangt, dass die *gesamte* Period danach liegt. --- ## 3. Mehrere `date`-Parameter kombinieren In der Praxis reicht ein einzelner Präfix selten – meist willst du einen **Bereich** definieren. FHIR-Server verknüpfen mehrere `date`-Parameter in derselben Query immer per **UND**. Vier typische Muster: ![Kombinationen](fhir-date-kombinationen.svg) | Kombination | Beispiel | Charakter | |---|---|---| | `ge` + `le` | `ge2023-01-01&le2023-12-31` | Geschlossenes Intervall (beide Grenzen inklusive) | | `gt` + `lt` | `gt2023-01-01<2023-12-31` | Offenes Intervall (beide Grenzen exklusive) | | `sa` + `eb` | `sa2023-01-01&eb2023-12-31` | Strikt getrennter Bereich, primär für Period-Werte | | `ge` + `lt` | `ge2023-06-01<2023-07-01` | Halboffenes Intervall `[start, ende)` – Standardmuster für „genau ein Monat" | Wenn du in Timestamp-lastigen ETL-Pipelines mit `[start, ende)` arbeitest, kommt dir `ge` + `lt` bekannt vor – es ist exakt dasselbe Muster wie bei klassischen Zeitfenster-Queries in SQL. --- ## 4. Die vollständige 3×3-Matrix aller Bereichs-Kombinationen Die vier Muster oben sind nur die gebräuchlichsten. Tatsächlich lässt sich **jede** Untergrenze mit **jeder** Obergrenze kombinieren: - Untergrenzen: `ge`, `gt`, `sa` - Obergrenzen: `le`, `lt`, `eb` Das ergibt 3 × 3 = **9 mögliche Kombinationen**, alle spec-konform: ![3x3 Matrix](fhir-date-matrix-3x3.svg) Sie unterscheiden sich nur darin, ob die jeweilige Grenze inklusiv (durchgezogene Linie) oder exklusiv (gestrichelte Linie) ist, und ob es sich um einen einfachen Werte-Vergleich (`ge`/`gt`/`le`/`lt`) oder einen strengen Period-Vergleich (`sa`/`eb`) handelt. Es gibt **keine explizite Ausschluss-Regel** im FHIR-Standard – jede Zelle dieser Matrix ist eine gültige, funktionierende Query. --- ## 5. Sonderfälle: Wenn Kombinationen redundant oder widersprüchlich werden Nicht jede syntaktisch gültige Kombination ist auch praktisch sinnvoll. Drei Kategorien solltest du kennen, bevor du sie versehentlich in einer generierten Query landen lässt: ![Sonderfälle](fhir-date-sonderfaelle.svg) ### a) Redundante Kombinationen Ändern nichts am Ergebnis, sind aber technisch kein Fehler: - `eq` + eine Grenze, die vom `eq`-Intervall ohnehin erfüllt wird (`eq2023-06-15&ge2020-01-01`) – die Zusatzbedingung ist überflüssig. - Zwei Bedingungen desselben Richtungstyps (`ge2020-01-01&ge2023-01-01`) – nur die strengere (spätere) Untergrenze wirkt effektiv. ### b) Kombinationen mit garantiert leerem Ergebnis Strukturell unmöglich zu erfüllen: - `eq` + `ne` auf denselben Wert (`eq2023-06-15&ne2023-06-15`) – sich gegenseitig ausschließende Bedingungen. - Untergrenze liegt zeitlich nach der Obergrenze (`ge2023-06-01&le2023-01-01`) – kein Datum erfüllt beides gleichzeitig. Der Server wird solche Queries **syntaktisch akzeptieren** und einfach eine leere Ergebnismenge zurückgeben – kein Fehler, aber auch keine hilfreiche Rückmeldung. Es lohnt sich, so etwas clientseitig vorab zu validieren. ### c) Ungewöhnliche, aber gültige Sonderfälle - **Drei oder mehr `date`-Parameter**, z. B. ein Jahresbereich mit ausgeschlossenem Einzeltag: `ge2023-01-01&le2023-12-31&ne2023-06-15`. - **`ap` kombiniert mit einer Grenze**, z. B. `ap2023-06-15&ge2023-01-01` – selten genutzt, da `ap` selbst schon unscharf ist und die Toleranzberechnung serverabhängig bleibt. --- ## 6. Praxis-Empfehlungen zum Schluss - Für einfache Bereichsfilter ist **`ge` + `lt`** (halboffenes Intervall) meist das robusteste Muster – es vermeidet Rundungsprobleme an der Precision-Grenze (kein Off-by-one bei „bis einschließlich 31.12."). - **`sa`/`eb`** nur einsetzen, wenn das Zielfeld tatsächlich ein `Period`- oder `Range`-Element ist. Bei einfachen `date`/`dateTime`-Feldern liefern sie in der Regel dasselbe Ergebnis wie `gt`/`lt` – der zusätzliche Ausdruck bringt dann keinen Mehrwert. - Vor dem Absetzen einer Multi-Parameter-Query lohnt sich ein kurzer Check auf logische Konsistenz zwischen Unter- und Obergrenze, um leere Ergebnisse durch Konfigurationsfehler in der eigenen Pipeline zu vermeiden. Mit diesen fünf Grafiken im Hinterkopf – ohne Präfix, alle neun Präfixe einzeln, typische Kombinationen, die volle 3×3-Matrix und die Sonderfälle – sollte die nächste `date`-Query im FHIR-Suchparameter kein Rätsel mehr sein.