Skip to content

Commit

Permalink
bug fixed for ZonedDateTime decode. issue alibaba#980
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Jan 8, 2017
1 parent 2756655 commit 6a787a7
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public class Jdk8DateCodec extends ContextObjectDeserializer implements ObjectSe
private final static DateTimeFormatter formatter_d10_de = DateTimeFormatter.ofPattern("dd.MM.yyyy");
private final static DateTimeFormatter formatter_d10_in = DateTimeFormatter.ofPattern("dd-MM-yyyy");

private final static DateTimeFormatter ISO_FIXED_FORMAT =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());

private final static String formatter_iso8601_pattern = "yyyy-MM-dd'T'HH:mm:ss";
private final static DateTimeFormatter formatter_iso8601 = DateTimeFormatter.ofPattern(formatter_iso8601_pattern);

Expand All @@ -58,7 +61,11 @@ public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName, S

DateTimeFormatter formatter = null;
if (format != null) {
formatter = DateTimeFormatter.ofPattern(format);
if (defaultPatttern.equals(format)) {
formatter = defaultFormatter;
} else {
formatter = DateTimeFormatter.ofPattern(format);
}
}

if (type == LocalDateTime.class) {
Expand Down Expand Up @@ -92,7 +99,11 @@ public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName, S
}
return (T) localDate;
} else if (type == ZonedDateTime.class) {
ZonedDateTime zonedDateTime = ZonedDateTime.parse(text);
if (formatter == defaultFormatter) {
formatter = ISO_FIXED_FORMAT;
}

ZonedDateTime zonedDateTime = parseZonedDateTime(text, formatter);

return (T) zonedDateTime;
} else if (type == OffsetDateTime.class) {
Expand Down Expand Up @@ -253,6 +264,76 @@ protected LocalDate parseLocalDate(String text, String format, DateTimeFormatter
: LocalDate.parse(text, formatter);
}

protected ZonedDateTime parseZonedDateTime(String text, DateTimeFormatter formatter) {
if (formatter == null) {
if (text.length() == 19) {
char c4 = text.charAt(4);
char c7 = text.charAt(7);
char c10 = text.charAt(10);
char c13 = text.charAt(13);
char c16 = text.charAt(16);
if (c13 == ':' && c16 == ':') {
if (c4 == '-' && c7 == '-') {
if (c10 == 'T') {
formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
} else if (c10 == ' ') {
formatter = defaultFormatter;
}
} else if (c4 == '-' && c7 == '-') {
formatter = defaultFormatter;
} else if (c4 == '/' && c7 == '/') { // tw yyyy/mm/dd
formatter = formatter_dt19_tw;
} else {
char c0 = text.charAt(0);
char c1 = text.charAt(1);
char c2 = text.charAt(2);
char c3 = text.charAt(3);
char c5 = text.charAt(5);
if (c2 == '/' && c5 == '/') { // mm/dd/yyyy or mm/dd/yyyy
int v0 = (c0 - '0') * 10 + (c1 - '0');
int v1 = (c3 - '0') * 10 + (c4 - '0');
if (v0 > 12) {
formatter = formatter_dt19_eur;
} else if (v1 > 12) {
formatter = formatter_dt19_us;
} else {
String country = Locale.getDefault().getCountry();

if (country.equals("US")) {
formatter = formatter_dt19_us;
} else if (country.equals("BR") //
|| country.equals("AU")) {
formatter = formatter_dt19_eur;
}
}
} else if (c2 == '.' && c5 == '.') { // dd.mm.yyyy
formatter = formatter_dt19_de;
} else if (c2 == '-' && c5 == '-') { // dd-mm-yyyy
formatter = formatter_dt19_in;
}
}
}
}

if (text.length() >= 17) {
char c4 = text.charAt(4);
if (c4 == '年') {
if (text.charAt(text.length() - 1) == '秒') {
formatter = formatter_dt19_cn_1;
} else {
formatter = formatter_dt19_cn;
}
} else if (c4 == '년') {
formatter = formatter_dt19_kr;
}
}
}

return formatter == null ? //
ZonedDateTime.parse(text) //
: ZonedDateTime.parse(text, formatter);
}

public int getFastMatchToken() {
return JSONToken.LITERAL_STRING;
}
Expand Down
30 changes: 30 additions & 0 deletions src/test/java/com/alibaba/json/bvt/jdk8/ZonedDateTimeTest2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.alibaba.json.bvt.jdk8;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import junit.framework.TestCase;
import org.junit.Assert;

import java.time.ZonedDateTime;
import java.time.temporal.TemporalField;

public class ZonedDateTimeTest2 extends TestCase {

public void test_for_issue() throws Exception {
VO vo = new VO();
vo.date = ZonedDateTime.now();

String text = JSON.toJSONString(vo);
System.out.println(text);

VO vo1 = JSON.parseObject(text, VO.class);

Assert.assertEquals(vo.date.getSecond(), vo1.date.getSecond());
}

public static class VO {
@JSONField(format="yyyy-MM-dd HH:mm:ss")
public ZonedDateTime date;

}
}

0 comments on commit 6a787a7

Please sign in to comment.