Skip to content

Commit d475ed1

Browse files
committed
Minor tweaks to #196, update release notes
1 parent 32f3f41 commit d475ed1

File tree

3 files changed

+73
-57
lines changed

3 files changed

+73
-57
lines changed

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/InstantDeserializer.java

+10-17
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
import com.fasterxml.jackson.databind.BeanProperty;
2424
import com.fasterxml.jackson.databind.DeserializationContext;
2525
import com.fasterxml.jackson.databind.DeserializationFeature;
26-
import com.fasterxml.jackson.databind.JsonDeserializer;
27-
import com.fasterxml.jackson.databind.JsonMappingException;
2826
import com.fasterxml.jackson.datatype.jsr310.DecimalUtils;
2927

3028
import java.io.IOException;
@@ -37,6 +35,7 @@
3735
import java.time.format.DateTimeFormatter;
3836
import java.time.temporal.Temporal;
3937
import java.time.temporal.TemporalAccessor;
38+
import java.util.Objects;
4039
import java.util.function.BiFunction;
4140
import java.util.function.Function;
4241
import java.util.regex.Pattern;
@@ -181,23 +180,17 @@ protected InstantDeserializer<T> withLeniency(Boolean leniency) {
181180
protected InstantDeserializer<T> withShape(JsonFormat.Shape shape) { return this; }
182181

183182
@SuppressWarnings("unchecked")
184-
@Override
185-
public JsonDeserializer<T> createContextual(DeserializationContext ctxt,
186-
BeanProperty property) throws JsonMappingException
183+
@Override // @since 2.12.1
184+
protected JSR310DateTimeDeserializerBase<?> _withFormatOverrides(DeserializationContext ctxt,
185+
BeanProperty property, JsonFormat.Value formatOverrides)
187186
{
188-
InstantDeserializer<T> deserializer =
189-
(InstantDeserializer<T>)super.createContextual(ctxt, property);
190-
JsonFormat.Value val = findFormatOverrides(ctxt, property, handledType());
191-
if (val != null) {
192-
deserializer = new InstantDeserializer<>(deserializer, val.getFeature(JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE));
193-
if (val.hasLenient()) {
194-
Boolean leniency = val.getLenient();
195-
if (leniency != null) {
196-
deserializer = deserializer.withLeniency(leniency);
197-
}
198-
}
187+
InstantDeserializer<T> deser = (InstantDeserializer<T>) super._withFormatOverrides(ctxt,
188+
property, formatOverrides);
189+
Boolean B = formatOverrides.getFeature(JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
190+
if (!Objects.equals(B, deser._adjustToContextTZOverride)) {
191+
return new InstantDeserializer<T>(deser, B);
199192
}
200-
return deserializer;
193+
return deser;
201194
}
202195

203196
@SuppressWarnings("unchecked")

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/JSR310DateTimeDeserializerBase.java

+57-40
Original file line numberDiff line numberDiff line change
@@ -101,53 +101,70 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
101101
BeanProperty property) throws JsonMappingException
102102
{
103103
JsonFormat.Value format = findFormatOverrides(ctxt, property, handledType());
104+
return (format == null) ? this : _withFormatOverrides(ctxt, property, format);
105+
}
106+
107+
/**
108+
* @param ctxt Active deserialization context
109+
* @param property (optional) Property on which this deserializer is used, or {@code null}
110+
* for root value
111+
* @param formatOverrides Format overrides to use (non-null)
112+
*
113+
* @return Either this deserializer as is, or newly constructed variant if created
114+
* for different configuration
115+
*
116+
* @since 2.12.1
117+
*/
118+
protected JSR310DateTimeDeserializerBase<?> _withFormatOverrides(DeserializationContext ctxt,
119+
BeanProperty property, JsonFormat.Value formatOverrides)
120+
{
104121
JSR310DateTimeDeserializerBase<?> deser = this;
105-
if (format != null) {
106-
// 17-Aug-2019, tatu: For 2.10 let's start considering leniency/strictness too
107-
if (format.hasLenient()) {
108-
Boolean leniency = format.getLenient();
109-
if (leniency != null) {
110-
deser = deser.withLeniency(leniency);
111-
}
122+
123+
// 17-Aug-2019, tatu: For 2.10 let's start considering leniency/strictness too
124+
if (formatOverrides.hasLenient()) {
125+
Boolean leniency = formatOverrides.getLenient();
126+
if (leniency != null) {
127+
deser = deser.withLeniency(leniency);
112128
}
113-
if (format.hasPattern()) {
114-
final String pattern = format.getPattern();
115-
final Locale locale = format.hasLocale() ? format.getLocale() : ctxt.getLocale();
116-
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
117-
if (acceptCaseInsensitiveValues(ctxt, format)) {
118-
builder.parseCaseInsensitive();
119-
}
120-
builder.appendPattern(pattern);
121-
DateTimeFormatter df;
122-
if (locale == null) {
123-
df = builder.toFormatter();
124-
} else {
125-
df = builder.toFormatter(locale);
126-
}
127-
128-
// [#148]: allow strict parsing
129-
if (!deser.isLenient()) {
130-
df = df.withResolverStyle(ResolverStyle.STRICT);
131-
}
132-
133-
// [#69]: For instant serializers/deserializers we need to configure the formatter with
134-
//a time zone picked up from JsonFormat annotation, otherwise serialization might not work
135-
if (format.hasTimeZone()) {
136-
df = df.withZone(format.getTimeZone().toZoneId());
137-
}
138-
deser = deser.withDateFormat(df);
129+
}
130+
if (formatOverrides.hasPattern()) {
131+
final String pattern = formatOverrides.getPattern();
132+
final Locale locale = formatOverrides.hasLocale() ? formatOverrides.getLocale() : ctxt.getLocale();
133+
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
134+
if (acceptCaseInsensitiveValues(ctxt, formatOverrides)) {
135+
builder.parseCaseInsensitive();
139136
}
140-
// [#58]: For LocalDate deserializers we need to configure the formatter with
141-
//a shape picked up from JsonFormat annotation, to decide if the value is EpochSeconds
142-
JsonFormat.Shape shape = format.getShape();
143-
if (shape != null && shape != _shape) {
144-
deser = deser.withShape(shape);
137+
builder.appendPattern(pattern);
138+
DateTimeFormatter df;
139+
if (locale == null) {
140+
df = builder.toFormatter();
141+
} else {
142+
df = builder.toFormatter(locale);
145143
}
146-
// any use for TimeZone?
144+
145+
// [#148]: allow strict parsing
146+
if (!deser.isLenient()) {
147+
df = df.withResolverStyle(ResolverStyle.STRICT);
148+
}
149+
150+
// [#69]: For instant serializers/deserializers we need to configure the formatter with
151+
//a time zone picked up from JsonFormat annotation, otherwise serialization might not work
152+
if (formatOverrides.hasTimeZone()) {
153+
df = df.withZone(formatOverrides.getTimeZone().toZoneId());
154+
}
155+
deser = deser.withDateFormat(df);
147156
}
157+
// [#58]: For LocalDate deserializers we need to configure the formatter with
158+
//a shape picked up from JsonFormat annotation, to decide if the value is EpochSeconds
159+
JsonFormat.Shape shape = formatOverrides.getShape();
160+
if (shape != null && shape != _shape) {
161+
deser = deser.withShape(shape);
162+
}
163+
// any use for TimeZone?
164+
148165
return deser;
149166
}
150-
167+
151168
private boolean acceptCaseInsensitiveValues(DeserializationContext ctxt, JsonFormat.Value format)
152169
{
153170
Boolean enabled = format.getFeature( Feature.ACCEPT_CASE_INSENSITIVE_VALUES);

release-notes/VERSION-2.x

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ Modules:
88
=== Releases ===
99
------------------------------------------------------------------------
1010

11+
2.12.1 (not yet released)
12+
13+
#196: `@JsonFormat` overriden features don't apply when there are no other
14+
options while deserializing ZonedDateTime
15+
(reported, fix contributed by Maciej D)
16+
1117
2.12.0 (29-Nov-2020)
1218
1319
#94: Deserialization of timestamps with UTC timezone to LocalDateTime

0 commit comments

Comments
 (0)