commit 6c848256314b2e0d806608ef2a9892350eeba81b Author: hmk Date: Wed Aug 12 11:00:22 2026 +0000 Add howto-fhir-date-parameter.md diff --git a/howto-fhir-date-parameter.md b/howto-fhir-date-parameter.md new file mode 100644 index 0000000..afcd44d --- /dev/null +++ b/howto-fhir-date-parameter.md @@ -0,0 +1,164 @@ +# 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.