-
Notifications
You must be signed in to change notification settings - Fork 6
JSTEP 5
(Back to JSTEP page)
(across) formats, defaults across JDK Classic, Joda and Java 8 date/time)
Related implementation issues:
- to be added -
Tatu Saloranta (@cowtowncoder)
2020-09-11: added a note about the possibility of adding serializers/deserializers
2020-06-16: adding a few additional notes from bug reports
2020-03-03: first skeletal revision
Both implementation and configuration aspects of 3 main date/time libraries/implementations:
- "Classic" JDKL
java.util.Date
,java.util.Calendar
(and formatting helpers) - Joda date/time
- Java 8 date/time (
java.time
) types
differ in many ways, especially regarding default handling, but also with respect to features supported.
It would be important to try to unify default configuration settings and configurability options, features supported.
In no particular order:
-
Mapper/Serialization/DeserializationFeature
settings both too simple (on/off) and meant as datatype-agnostic to be sufficient for all configuration needs - Format strings used for JDK-Classic/Joda/Java8-DateTime may differ (i.e. same format string not applicable to all), but
@JsonFormat
(and related Config Overrides) used interchangeably (can use per-type overrides, but global default would be same; documentation gets tricky) - There are also obvious challenges in how to apply different configuration settings (and if possible, allow layered configuration from global/per-type/per-property) that may be overlapping or even conflicting.
- There is also the question of which settings are per-mapper, immutable during use, and which need to be per-call changeable (DeserializationFeature is one of limited number of things that can be changed in this way).
No concrete proposal yet.
Since one concrete problem is that of unit of timestamp:
- Java "classic": milliseconds since epoch (1970-01-01T00:00Z)
- Unix seconds since epoch
- Java 8 nanoseconds since... something?
Would it make sense to add unit
(or timeUnit
) property for @JsonFormat
?
On one hand, it is bit datatype-specific, but there is one big benefit: ability to set format defaults, and overrides (both programmatically and via annotations) would make implementation relatively easy
Note that, related to this, for a proposed fix for DurationDeserializer
, the plan is to add support for "pattern" in JsonFormat
, so that support could be extended to other types. See issue #184.
@JsonFormat(pattern = "h")
With 2.10 and later, ObjectMapper
configuration is vastly improved by "Builder" style construction.
This would make it easier to add richer configuration options: specifically, while [De]SerializationFeature
on/off options are simple, their use does not work well with multiple-options/choices case.
So maybe we should consider datatype-specific Config object like DateTimeConfig
?
The idea is to create subset of Date/Time-specific settings, possibly including simple on/off features (DateTimeConfig.Feature.xxx), but not limited to just on/off settings.
What we probably should start doing is to collect kinds of things that need configuring.
Coercion settings would be one such feature/aspect. See the date-time-config
label for related bugs.
Perhaps a guiding principle should be "Use the right type for your data", i.e.
If timezone information is to be used, proper type -- "zoned" date/time -- needs to be used Cowtowncoder)
This idea was sparked by a solution to Allow Instant to be serialized as epochSecond without the fraction part where, instead of requiring a new [De]SerializationFeature
or an annotation, a _new _serializer was added by extending JsonSerializer
. This helps address issue #3 above, i.e. using the proper type helps keep the classes consistent and avoids unnecessary complexity, and even bugs, as in the case where one change inadvertently causes something else to break. As an example, see Deserialization of timestamps with UTC timezone to LocalDateTime doesn't yield correct time where @erwich explains a particular test case to illustrate how a previous fix can, in certain cases, cause incorrect values to be parsed.
Of course, the Java 8 Date/Time library was designed to be extended so this solution is already there and available, but (unless included in the date time module) requires some work on the part of the implementer to add the class, and then additional work if the interface changes in a later Jackson release.
This solution should be used with care as right now, the Date/Time module is mostly aligned with the existing Java classes and this could fall into the trap of a proliferation / explosion of new serializers/deserializers, and further run into the issue of consistency, i.e. do I solve this via an annotation, a [De]SerializationFeature
on/off switch, or am I using the wrong type completely?