Skip to content

Commit 0ecb478

Browse files
committed
Initial part of #281 to add JavaTimeFeature.NORMALIZE_DESERIALIZED_ZONE_ID
1 parent 572cde0 commit 0ecb478

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/JavaTimeFeature.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@
1010
public enum JavaTimeFeature implements JacksonFeature
1111
{
1212
/**
13-
* Placeholder
13+
* Feature that determines whether {@link java.time.ZoneId} is normalized
14+
* (via call to {@code java.time.ZoneId#normalized()}) when deserializing
15+
* types like {@link java.time.ZonedDateTime}.
16+
*<p>
17+
* Default setting is enabled, for backwards-compatibility with
18+
* Jackson 2.15.
1419
*/
15-
BOGUS(false);
20+
NORMALIZE_DESERIALID_ZONE_ID(true);
1621

1722
/**
1823
* Whether feature is enabled or disabled by default.

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

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ public class InstantDeserializer<T extends Temporal>
6767
a -> Instant.ofEpochMilli(a.value),
6868
a -> Instant.ofEpochSecond(a.integer, a.fraction),
6969
null,
70-
true // yes, replace zero offset with Z
70+
true, // yes, replace zero offset with Z
71+
true // default: yes, normalize ZoneId
7172
);
7273

7374
public static final InstantDeserializer<OffsetDateTime> OFFSET_DATE_TIME = new InstantDeserializer<>(
@@ -76,7 +77,8 @@ public class InstantDeserializer<T extends Temporal>
7677
a -> OffsetDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId),
7778
a -> OffsetDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId),
7879
(d, z) -> (d.isEqual(OffsetDateTime.MIN) || d.isEqual(OffsetDateTime.MAX) ? d : d.withOffsetSameInstant(z.getRules().getOffset(d.toLocalDateTime()))),
79-
true // yes, replace zero offset with Z
80+
true, // yes, replace zero offset with Z
81+
true // default: yes, normalize ZoneId
8082
);
8183

8284
public static final InstantDeserializer<ZonedDateTime> ZONED_DATE_TIME = new InstantDeserializer<>(
@@ -85,7 +87,8 @@ public class InstantDeserializer<T extends Temporal>
8587
a -> ZonedDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId),
8688
a -> ZonedDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId),
8789
ZonedDateTime::withZoneSameInstant,
88-
false // keep zero offset and Z separate since zones explicitly supported
90+
false, // keep zero offset and Z separate since zones explicitly supported
91+
true // default: yes, normalize ZoneId
8992
);
9093

9194
protected final Function<FromIntegerArguments, T> fromMilliseconds;
@@ -119,13 +122,21 @@ public class InstantDeserializer<T extends Temporal>
119122
*/
120123
protected final Boolean _readTimestampsAsNanosOverride;
121124

125+
/**
126+
* Flag set from
127+
* {@link com.fasterxml.jackson.datatype.jsr310.JavaTimeFeature#NORMALIZE_DESERIALIZED_ZONE_ID} to
128+
* determine whether {@link ZoneId} is to be normalized during deserialization.
129+
*/
130+
protected final boolean _normalizeZoneId;
131+
122132
protected InstantDeserializer(Class<T> supportedType,
123133
DateTimeFormatter formatter,
124134
Function<TemporalAccessor, T> parsedToValue,
125135
Function<FromIntegerArguments, T> fromMilliseconds,
126136
Function<FromDecimalArguments, T> fromNanoseconds,
127137
BiFunction<T, ZoneId, T> adjust,
128-
boolean replaceZeroOffsetAsZ)
138+
boolean replaceZeroOffsetAsZ,
139+
boolean normalizeZoneId)
129140
{
130141
super(supportedType, formatter);
131142
this.parsedToValue = parsedToValue;
@@ -135,6 +146,7 @@ protected InstantDeserializer(Class<T> supportedType,
135146
this.replaceZeroOffsetAsZ = replaceZeroOffsetAsZ;
136147
this._adjustToContextTZOverride = null;
137148
this._readTimestampsAsNanosOverride = null;
149+
_normalizeZoneId = normalizeZoneId;
138150
}
139151

140152
@SuppressWarnings("unchecked")
@@ -148,6 +160,7 @@ protected InstantDeserializer(InstantDeserializer<T> base, DateTimeFormatter f)
148160
replaceZeroOffsetAsZ = (_formatter == DateTimeFormatter.ISO_INSTANT);
149161
_adjustToContextTZOverride = base._adjustToContextTZOverride;
150162
_readTimestampsAsNanosOverride = base._readTimestampsAsNanosOverride;
163+
_normalizeZoneId = base._normalizeZoneId;
151164
}
152165

153166
@SuppressWarnings("unchecked")
@@ -161,6 +174,7 @@ protected InstantDeserializer(InstantDeserializer<T> base, Boolean adjustToConte
161174
replaceZeroOffsetAsZ = base.replaceZeroOffsetAsZ;
162175
_adjustToContextTZOverride = adjustToContextTimezoneOverride;
163176
_readTimestampsAsNanosOverride = base._readTimestampsAsNanosOverride;
177+
_normalizeZoneId = base._normalizeZoneId;
164178
}
165179

166180
@SuppressWarnings("unchecked")
@@ -174,6 +188,7 @@ protected InstantDeserializer(InstantDeserializer<T> base, DateTimeFormatter f,
174188
replaceZeroOffsetAsZ = (_formatter == DateTimeFormatter.ISO_INSTANT);
175189
_adjustToContextTZOverride = base._adjustToContextTZOverride;
176190
_readTimestampsAsNanosOverride = base._readTimestampsAsNanosOverride;
191+
_normalizeZoneId = base._normalizeZoneId;
177192
}
178193

179194
/**
@@ -194,6 +209,7 @@ protected InstantDeserializer(InstantDeserializer<T> base,
194209
replaceZeroOffsetAsZ = base.replaceZeroOffsetAsZ;
195210
_adjustToContextTZOverride = adjustToContextTimezoneOverride;
196211
_readTimestampsAsNanosOverride = readTimestampsAsNanosOverride;
212+
_normalizeZoneId = base._normalizeZoneId;
197213
}
198214

199215
@Override
@@ -364,7 +380,11 @@ private ZoneId getZone(DeserializationContext context)
364380
// Instants are always in UTC, so don't waste compute cycles
365381
// Normalizing the zone to prevent discrepancies.
366382
// See https://github.com/FasterXML/jackson-modules-java8/pull/267 for details
367-
return (_valueClass == Instant.class) ? null : context.getTimeZone().toZoneId().normalized();
383+
if (_valueClass == Instant.class) {
384+
return null;
385+
}
386+
ZoneId zoneId = context.getTimeZone().toZoneId();
387+
return _normalizeZoneId ? zoneId.normalized() : zoneId;
368388
}
369389

370390
private String replaceZeroOffsetAsZIfNecessary(String text)

0 commit comments

Comments
 (0)