This commit breaks FHIRDate into four classes:
- FHIRDate
- FHIRDateTime
- FHIRInstant
- FHIRTime
BREAKING CHANGES:
- If consuming code were inspecting the elementProperties array and
doing a check like `element_type is FHIRDate`, that will now fail
for `datetime`, `instant`, and `time` elements. Backwards
compatibility is however maintained for checks written like
`issubclass(element_type, FHIRDate)`.
Instances have a similar resolution: `isinstance(obj, FHIRDate)` will
still work.
- If consuming code were manually creating FHIRDate objects
themselves with a time component, that will now fail with a
ValueError.
Since the first item is unavoidable if we want to fix the bugs listed
below and has a workaround that works before and after this change,
and the second item is not an expected workflow, I hope that such
breaking changes do not cause too much harm for consumers.
BUG FIXES:
- FHIR `time` fields are now correctly parsed. Previously, a time of
"10:12:14" would result in a **date** of "1001-01-01"
- Passing too much detail to a `date` field or too little detail to an
`instant` field will now correctly throw a validation error.
For example, a Patient.birthDate field with a time. Or an
Observation.issued field with just a year.
- Sub-seconds would be incorrectly chopped off of a `datetime`'s
`.isostring` (which the FHIR spec allows us to do) and an `instant`'s
`.isostring` (which the FHIR spec **does not** allow us to do).
The `.date` Python representation and the `.as_json()` call would
both work correctly and keep the sub-seconds. Only `.isostring` was
affected.
IMPROVEMENTS:
- Leap seconds are now half-supported. The FHIR spec says clients
"SHOULD accept and handle leap seconds gracefully", which we do...
By dropping the leap second on the floor and rolling back to :59.
But this is an improvement on previous behavior of a validation
error. The `.as_json()` value will still preserve the leap second.
- The `.date` field is now always the appropriate type (datetime.date
for FHIRDate, datetime.datetime for FHIRDateTime and FHIRInstant,
and datetime.time for FHIRTime). Previously, a `datetime` field might
result in a datetime.date if only given a date portion. (Which isn't
entirely wrong, but consistently providing the same data type is
useful.)
- The new classes have appropriately named fields in addition to the
backwards-compatible `.date` field -- FHIRDateTime.datetime,
FHIRInstant.datetime, and FHIRTime.time. These will always be the
same value as `.date` for now - but in a future major release, the
`.date` alias may be dropped.
- The dependency on isodate can now be dropped. It is lightly
maintained and the stdlib can handle most of its job nowadays.
- Much better class documentation for what sort of things are
supported and which are not.