-
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)
Tatu Saloranta (@cowtowncoder)
- 2022-09-18: minor changes
- 2021-02-01: add example of the kinds of things that need configuring.
- 2020-10-13: add idea about JsonFormat pattern.
- 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
No progress as of Jackson 2.18; not yet started.
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.14 and later, a new DatatypeFeature
functionality was introduced (originally with JsonNodeFeature
and EnumFeature
).
This makes it easy to add further feature sets, specifically DateTimeFeature
, with minimal code changes and convenient if simple global default configurability specific to Date/Time value types.
What we probably should start doing is to collect kinds of things that need configuring. Coercion settings would be one such feature/aspect.
Examples:
- Allow the year format to be configurable, for example setting the format to 'uuuu' (year) instead of 'yyyy' (year-of-era). This would only affect cases where defaults are not overridden by annotation or config overrides for types.
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?
JSTEP-2 proposes some changes to DeserializationFeature
s relevant for Date/Time handling.
We may consider alternatively moving some of those features under DateTimeFeature
s.