diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java index a708897e9..d1bfc29f5 100644 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java @@ -20,11 +20,13 @@ import java.util.Locale; import java.util.TimeZone; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONScanner; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.serializer.*; +import com.alibaba.fastjson.util.TypeUtils; public class Jdk8DateCodec extends ContextObjectDeserializer implements ObjectSerializer, ContextObjectSerializer, ObjectDeserializer { @@ -231,6 +233,23 @@ public class Jdk8DateCodec extends ContextObjectDeserializer implements ObjectSe } throw new UnsupportedOperationException(); + } else if (lexer.token() == JSONToken.LBRACE) { + JSONObject object = parser.parseObject(); + + if (type == Instant.class) { + Object epochSecond = object.get("epochSecond"); + Object nano = object.get("nano"); + if (epochSecond instanceof Number && nano instanceof Number) { + return (T) Instant.ofEpochSecond( + TypeUtils.longExtractValue((Number) epochSecond) + , TypeUtils.longExtractValue((Number) nano)); + } + + if (epochSecond instanceof Number) { + return (T) Instant.ofEpochSecond( + TypeUtils.longExtractValue((Number) epochSecond)); + } + } } else { throw new UnsupportedOperationException(); } diff --git a/src/main/java/com/alibaba/fastjson/serializer/JodaCodec.java b/src/main/java/com/alibaba/fastjson/serializer/JodaCodec.java index 219b8150d..4413b78f1 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/JodaCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JodaCodec.java @@ -1,6 +1,7 @@ package com.alibaba.fastjson.serializer; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; @@ -11,6 +12,7 @@ import java.util.Locale; import java.util.TimeZone; import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.util.TypeUtils; import org.joda.time.*; import org.joda.time.format.*; @@ -156,7 +158,7 @@ public class JodaCodec implements ObjectSerializer, ContextObjectSerializer, Obj return (T) new DateTime(millis, DateTimeZone.forTimeZone(timeZone)); } - LocalDateTime localDateTime = new LocalDateTime(millis, DateTimeZone.forTimeZone(timeZone)); + LocalDateTime localDateTime = new LocalDateTime(millis, DateTimeZone.forTimeZone(timeZone)); if (type == LocalDateTime.class) { return (T) localDateTime; } @@ -176,6 +178,23 @@ public class JodaCodec implements ObjectSerializer, ContextObjectSerializer, Obj } throw new UnsupportedOperationException(); + } else if (lexer.token() == JSONToken.LBRACE) { + JSONObject object = parser.parseObject(); + + if (type == Instant.class) { + Object epochSecond = object.get("epochSecond"); + + if (epochSecond instanceof Number) { + return (T) Instant.ofEpochSecond( + TypeUtils.longExtractValue((Number) epochSecond)); + } + + Object millis = object.get("millis"); + if (millis instanceof Number) { + return (T) Instant.ofEpochMilli( + TypeUtils.longExtractValue((Number) millis)); + } + } } else { throw new UnsupportedOperationException(); } diff --git a/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3539.java b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3539.java new file mode 100644 index 000000000..ac8ee4a6c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3539.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.issue_3500; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.time.Instant; + +public class Issue3539 extends TestCase { + public void test_for_issue() throws Exception { + String str = "{\"date\":{\"nano\":140000000,\"epochSecond\":1605106869}}"; + Bean bean = JSON.parseObject(str, Bean.class); + assertNotNull(bean.date); + JSON.toJSONString(bean); + + JSON.parseObject(str) + .toJavaObject(Bean.class); + } + + public void test_for_issue_joda() throws Exception { + String str = "{\"date\":{\"epochSecond\":1605106869}}"; + JodaBean bean = JSON.parseObject(str, JodaBean.class); + assertNotNull(bean.date); + JSON.toJSONString(bean); + + JSON.parseObject(str) + .toJavaObject(JodaBean.class); + } + + public void test_for_issue_joda2() throws Exception { + String str = "{\"date\":{\"millis\":1605364826724}}"; + JodaBean bean = JSON.parseObject(str, JodaBean.class); + assertNotNull(bean.date); + JSON.toJSONString(bean); + + JSON.parseObject(str) + .toJavaObject(JodaBean.class); + } + + public static class Bean { + public Instant date; + } + + public static class JodaBean { + public org.joda.time.Instant date; + } +}