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

Add Support for JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE #80

Merged
merged 1 commit into from
Jun 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@

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

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonTokenId;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.datatype.jsr310.DecimalUtils;

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

protected final Boolean adjustToContextTimezoneOverride;

protected InstantDeserializer(Class<T> supportedType,
DateTimeFormatter formatter,
Function<TemporalAccessor, T> parsedToValue,
Expand All @@ -105,6 +110,7 @@ protected InstantDeserializer(Class<T> supportedType,
this.fromNanoseconds = fromNanoseconds;
this.adjust = adjust == null ? ((d, z) -> d) : adjust;
this.replace0000AsZ = replace0000AsZ;
this.adjustToContextTimezoneOverride = null;
}

@SuppressWarnings("unchecked")
Expand All @@ -116,6 +122,19 @@ protected InstantDeserializer(InstantDeserializer<T> base, DateTimeFormatter f)
fromNanoseconds = base.fromNanoseconds;
adjust = base.adjust;
replace0000AsZ = (_formatter == DateTimeFormatter.ISO_INSTANT);
adjustToContextTimezoneOverride = base.adjustToContextTimezoneOverride;
}

@SuppressWarnings("unchecked")
protected InstantDeserializer(InstantDeserializer<T> base, Boolean adjustToContextTimezoneOverride)
{
super((Class<T>) base.handledType(), base._formatter);
parsedToValue = base.parsedToValue;
fromMilliseconds = base.fromMilliseconds;
fromNanoseconds = base.fromNanoseconds;
adjust = base.adjust;
replace0000AsZ = base.replace0000AsZ;
this.adjustToContextTimezoneOverride = adjustToContextTimezoneOverride;
}

@Override
Expand Down Expand Up @@ -173,7 +192,7 @@ public T deserialize(JsonParser parser, DeserializationContext context) throws I
try {
TemporalAccessor acc = _formatter.parse(string);
value = parsedToValue.apply(acc);
if (context.isEnabled(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)) {
if (isAdjustToContextTimezone(context)) {
return adjust.apply(value, this.getZone(context));
}
} catch (DateTimeException e) {
Expand All @@ -190,6 +209,27 @@ public T deserialize(JsonParser parser, DeserializationContext context) throws I
throw context.mappingException("Expected type float, integer, or string.");
}

@SuppressWarnings("unchecked")
@Override
public JsonDeserializer<T> createContextual(DeserializationContext ctxt,
BeanProperty property) throws JsonMappingException
{
InstantDeserializer<T> deserializer =
(InstantDeserializer<T>)super.createContextual(ctxt, property);
if (deserializer != this) {
JsonFormat.Value val = findFormatOverrides(ctxt, property, handledType());
if (val != null) {
return new InstantDeserializer<>(deserializer, val.getFeature(JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE));
}
}
return this;
}

private boolean isAdjustToContextTimezone(DeserializationContext context) {
return adjustToContextTimezoneOverride != null ? adjustToContextTimezoneOverride :
context.isEnabled(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
}

/**
* Helper method to find Strings of form "all digits" and "digits-comma-digits"
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.fasterxml.jackson.datatype.jsr310;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectReader;
Expand All @@ -10,6 +11,7 @@
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeParseException;
import java.util.TimeZone;

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

public static class WithContextTimezoneDateFieldBean {
@JsonFormat(shape = JsonFormat.Shape.STRING,
pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", with = JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
public OffsetDateTime date;
}

@Test
public void testDeserializationWithContextTimezoneFeatureOverride() throws Exception
{
String inputStr = "{\"date\":\"2016-05-13T17:24:40.545+03\"}";
WithContextTimezoneDateFieldBean result = newMapper().setTimeZone(TimeZone.getTimeZone("UTC")).
disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE).readValue(inputStr, WithContextTimezoneDateFieldBean.class);
notNull(result);
expect(OffsetDateTime.of(2016, 5, 13, 14, 24, 40, 545000000, ZoneOffset.UTC), result.date);
}

public static class WithoutContextTimezoneDateFieldBean {
@JsonFormat(shape = JsonFormat.Shape.STRING,
pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", without = JsonFormat.Feature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
public OffsetDateTime date;
}

@Test
public void testDeserializationWithoutContextTimezoneFeatureOverride() throws Exception
{
String inputStr = "{\"date\":\"2016-05-13T17:24:40.545+03\"}";
WithoutContextTimezoneDateFieldBean result = newMapper().setTimeZone(TimeZone.getTimeZone("UTC")).
enable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE).readValue(inputStr, WithoutContextTimezoneDateFieldBean.class);
notNull(result);
expect(OffsetDateTime.of(2016, 5, 13, 17, 24, 40, 545000000, ZoneOffset.ofHours(3)), result.date);
}

@Test
public void testBadDeserializationAsString01() throws Throwable
{
Expand Down