Skip to content
This repository was archived by the owner on Nov 7, 2019. It is now read-only.

Commit e139142

Browse files
authored
Merge pull request #80 from joxerTMD/master
add Support for JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE
2 parents 66644bd + 576ba33 commit e139142

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed

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

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@
1616

1717
package com.fasterxml.jackson.datatype.jsr310.deser;
1818

19+
import com.fasterxml.jackson.annotation.JsonFormat;
1920
import com.fasterxml.jackson.core.JsonParser;
2021
import com.fasterxml.jackson.core.JsonTokenId;
22+
import com.fasterxml.jackson.databind.BeanProperty;
2123
import com.fasterxml.jackson.databind.DeserializationContext;
2224
import com.fasterxml.jackson.databind.DeserializationFeature;
2325
import com.fasterxml.jackson.databind.JsonDeserializer;
26+
import com.fasterxml.jackson.databind.JsonMappingException;
2427
import com.fasterxml.jackson.datatype.jsr310.DecimalUtils;
2528

2629
import java.io.IOException;
@@ -91,6 +94,8 @@ public class InstantDeserializer<T extends Temporal>
9194
*/
9295
protected final boolean replace0000AsZ;
9396

97+
protected final Boolean adjustToContextTimezoneOverride;
98+
9499
protected InstantDeserializer(Class<T> supportedType,
95100
DateTimeFormatter formatter,
96101
Function<TemporalAccessor, T> parsedToValue,
@@ -105,6 +110,7 @@ protected InstantDeserializer(Class<T> supportedType,
105110
this.fromNanoseconds = fromNanoseconds;
106111
this.adjust = adjust == null ? ((d, z) -> d) : adjust;
107112
this.replace0000AsZ = replace0000AsZ;
113+
this.adjustToContextTimezoneOverride = null;
108114
}
109115

110116
@SuppressWarnings("unchecked")
@@ -116,6 +122,19 @@ protected InstantDeserializer(InstantDeserializer<T> base, DateTimeFormatter f)
116122
fromNanoseconds = base.fromNanoseconds;
117123
adjust = base.adjust;
118124
replace0000AsZ = (_formatter == DateTimeFormatter.ISO_INSTANT);
125+
adjustToContextTimezoneOverride = base.adjustToContextTimezoneOverride;
126+
}
127+
128+
@SuppressWarnings("unchecked")
129+
protected InstantDeserializer(InstantDeserializer<T> base, Boolean adjustToContextTimezoneOverride)
130+
{
131+
super((Class<T>) base.handledType(), base._formatter);
132+
parsedToValue = base.parsedToValue;
133+
fromMilliseconds = base.fromMilliseconds;
134+
fromNanoseconds = base.fromNanoseconds;
135+
adjust = base.adjust;
136+
replace0000AsZ = base.replace0000AsZ;
137+
this.adjustToContextTimezoneOverride = adjustToContextTimezoneOverride;
119138
}
120139

121140
@Override
@@ -173,7 +192,7 @@ public T deserialize(JsonParser parser, DeserializationContext context) throws I
173192
try {
174193
TemporalAccessor acc = _formatter.parse(string);
175194
value = parsedToValue.apply(acc);
176-
if (context.isEnabled(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)) {
195+
if (isAdjustToContextTimezone(context)) {
177196
return adjust.apply(value, this.getZone(context));
178197
}
179198
} catch (DateTimeException e) {
@@ -190,6 +209,27 @@ public T deserialize(JsonParser parser, DeserializationContext context) throws I
190209
throw context.mappingException("Expected type float, integer, or string.");
191210
}
192211

212+
@SuppressWarnings("unchecked")
213+
@Override
214+
public JsonDeserializer<T> createContextual(DeserializationContext ctxt,
215+
BeanProperty property) throws JsonMappingException
216+
{
217+
InstantDeserializer<T> deserializer =
218+
(InstantDeserializer<T>)super.createContextual(ctxt, property);
219+
if (deserializer != this) {
220+
JsonFormat.Value val = findFormatOverrides(ctxt, property, handledType());
221+
if (val != null) {
222+
return new InstantDeserializer<>(deserializer, val.getFeature(JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE));
223+
}
224+
}
225+
return this;
226+
}
227+
228+
private boolean isAdjustToContextTimezone(DeserializationContext context) {
229+
return adjustToContextTimezoneOverride != null ? adjustToContextTimezoneOverride :
230+
context.isEnabled(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
231+
}
232+
193233
/**
194234
* Helper method to find Strings of form "all digits" and "digits-comma-digits"
195235
*/

src/test/java/com/fasterxml/jackson/datatype/jsr310/TestOffsetDateTimeDeserialization.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.fasterxml.jackson.datatype.jsr310;
22

3+
import com.fasterxml.jackson.annotation.JsonFormat;
34
import com.fasterxml.jackson.databind.DeserializationFeature;
45
import com.fasterxml.jackson.databind.JsonMappingException;
56
import com.fasterxml.jackson.databind.ObjectReader;
@@ -10,6 +11,7 @@
1011
import java.time.OffsetDateTime;
1112
import java.time.ZoneOffset;
1213
import java.time.format.DateTimeParseException;
14+
import java.util.TimeZone;
1315

1416
import static org.junit.Assert.assertEquals;
1517
import static org.junit.Assert.assertNotNull;
@@ -44,6 +46,38 @@ public void testDeserializationAsString03() throws Exception
4446
expect(OffsetDateTime.of(2000, 1, 1, 12, 0, 0, 0, ZoneOffset.ofHours(5)), parsed) ;
4547
}
4648

49+
public static class WithContextTimezoneDateFieldBean {
50+
@JsonFormat(shape = JsonFormat.Shape.STRING,
51+
pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", with = JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
52+
public OffsetDateTime date;
53+
}
54+
55+
@Test
56+
public void testDeserializationWithContextTimezoneFeatureOverride() throws Exception
57+
{
58+
String inputStr = "{\"date\":\"2016-05-13T17:24:40.545+03\"}";
59+
WithContextTimezoneDateFieldBean result = newMapper().setTimeZone(TimeZone.getTimeZone("UTC")).
60+
disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE).readValue(inputStr, WithContextTimezoneDateFieldBean.class);
61+
notNull(result);
62+
expect(OffsetDateTime.of(2016, 5, 13, 14, 24, 40, 545000000, ZoneOffset.UTC), result.date);
63+
}
64+
65+
public static class WithoutContextTimezoneDateFieldBean {
66+
@JsonFormat(shape = JsonFormat.Shape.STRING,
67+
pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", without = JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
68+
public OffsetDateTime date;
69+
}
70+
71+
@Test
72+
public void testDeserializationWithoutContextTimezoneFeatureOverride() throws Exception
73+
{
74+
String inputStr = "{\"date\":\"2016-05-13T17:24:40.545+03\"}";
75+
WithoutContextTimezoneDateFieldBean result = newMapper().setTimeZone(TimeZone.getTimeZone("UTC")).
76+
enable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE).readValue(inputStr, WithoutContextTimezoneDateFieldBean.class);
77+
notNull(result);
78+
expect(OffsetDateTime.of(2016, 5, 13, 17, 24, 40, 545000000, ZoneOffset.ofHours(3)), result.date);
79+
}
80+
4781
@Test
4882
public void testBadDeserializationAsString01() throws Throwable
4983
{

0 commit comments

Comments
 (0)