Skip to content

Commit 834a333

Browse files
committed
deserialize LocalDate support more input format.
1 parent 097f637 commit 834a333

File tree

4 files changed

+136
-5
lines changed

4 files changed

+136
-5
lines changed

core/src/main/java/com/alibaba/fastjson2/JSONReaderJSONB.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4401,6 +4401,14 @@ public final LocalDate readLocalDate() {
44014401
return LocalDate.of(year, month, dayOfMonth);
44024402
}
44034403

4404+
if (type == BC_LOCAL_DATETIME) {
4405+
return readLocalDateTime().toLocalDate();
4406+
}
4407+
4408+
if (type == BC_TIMESTAMP_WITH_TIMEZONE) {
4409+
return readZonedDateTime().toLocalDate();
4410+
}
4411+
44044412
if (type >= BC_STR_ASCII_FIX_MIN && type <= BC_STR_ASCII_FIX_MAX) {
44054413
int len = getStringLength();
44064414
switch (len) {
@@ -4413,6 +4421,10 @@ public final LocalDate readLocalDate() {
44134421
case 11:
44144422
return readLocalDate11();
44154423
default:
4424+
if (bytes[offset + len] == 'Z') {
4425+
ZonedDateTime zdt = readZonedDateTime();
4426+
return zdt.toLocalDate();
4427+
}
44164428
break;
44174429
}
44184430
throw new JSONException("TODO : " + len + ", " + readString());
@@ -4437,7 +4449,7 @@ public final LocalDate readLocalDate() {
44374449
}
44384450
}
44394451

4440-
throw new UnsupportedOperationException();
4452+
throw new JSONException("not support type : " + typeName((byte) type));
44414453
}
44424454

44434455
@Override
@@ -4457,6 +4469,10 @@ public final LocalDateTime readLocalDateTime() {
44574469
return LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nano);
44584470
}
44594471

4472+
if (type == BC_TIMESTAMP_WITH_TIMEZONE) {
4473+
return readZonedDateTime().toLocalDateTime();
4474+
}
4475+
44604476
if (type >= BC_STR_ASCII_FIX_MIN && type <= BC_STR_ASCII_FIX_MAX) {
44614477
int len = getStringLength();
44624478
LocalDate localDate;
@@ -4508,7 +4524,7 @@ public final LocalDateTime readLocalDateTime() {
45084524
throw new JSONException("TODO : " + len + ", " + readString());
45094525
}
45104526

4511-
throw new UnsupportedOperationException();
4527+
throw new JSONException("not support type : " + typeName((byte) type));
45124528
}
45134529

45144530
@Override
@@ -4700,6 +4716,24 @@ public final ZonedDateTime readZonedDateTime() {
47004716
Instant instant = Instant.ofEpochSecond(seconds);
47014717
return ZonedDateTime.ofInstant(instant, DEFAULT_ZONE_ID);
47024718
}
4719+
case BC_LOCAL_DATE: {
4720+
int year = (bytes[offset++] << 8) + (bytes[offset++] & 0xFF);
4721+
byte month = bytes[offset++];
4722+
byte dayOfMonth = bytes[offset++];
4723+
LocalDate localDate = LocalDate.of(year, month, dayOfMonth);
4724+
return ZonedDateTime.of(localDate, LocalTime.MIN, DEFAULT_ZONE_ID);
4725+
}
4726+
case BC_LOCAL_DATETIME: {
4727+
int year = (bytes[offset++] << 8) + (bytes[offset++] & 0xFF);
4728+
byte month = bytes[offset++];
4729+
byte dayOfMonth = bytes[offset++];
4730+
byte hour = bytes[offset++];
4731+
byte minute = bytes[offset++];
4732+
byte second = bytes[offset++];
4733+
int nano = readInt32Value();
4734+
LocalDateTime ldt = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nano);
4735+
return ZonedDateTime.of(ldt, DEFAULT_ZONE_ID);
4736+
}
47034737
case BC_INT64:
47044738
case BC_TIMESTAMP_MILLIS: {
47054739
long millis =
@@ -4740,7 +4774,7 @@ public final ZonedDateTime readZonedDateTime() {
47404774
}
47414775
break;
47424776
}
4743-
throw new UnsupportedOperationException();
4777+
throw new JSONException("type not support : " + JSONB.typeName((byte) type));
47444778
}
47454779

47464780
@Override

core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5943,7 +5943,14 @@ protected final LocalDateTime readLocalDateTimeX(int len) {
59435943
throw new JSONException("date only support string input");
59445944
}
59455945

5946-
LocalDateTime ldt = DateUtils.parseLocalDateTimeX(chars, offset, len);
5946+
LocalDateTime ldt;
5947+
if (chars[offset + len - 1] == 'Z') {
5948+
ZonedDateTime zdt = DateUtils.parseZonedDateTime(chars, offset, len);
5949+
ldt = zdt.toLocalDateTime();
5950+
} else {
5951+
ldt = DateUtils.parseLocalDateTimeX(chars, offset, len);
5952+
}
5953+
59475954
if (ldt == null) {
59485955
return null;
59495956
}

core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5835,7 +5835,14 @@ protected final LocalDateTime readLocalDateTimeX(int len) {
58355835
throw new JSONException("date only support string input");
58365836
}
58375837

5838-
LocalDateTime ldt = DateUtils.parseLocalDateTimeX(bytes, offset, len);
5838+
LocalDateTime ldt;
5839+
if (bytes[offset + len - 1] == 'Z') {
5840+
ZonedDateTime zdt = DateUtils.parseZonedDateTime(bytes, offset, len);
5841+
ldt = zdt.toLocalDateTime();
5842+
} else {
5843+
ldt = DateUtils.parseLocalDateTimeX(bytes, offset, len);
5844+
}
5845+
58395846
if (ldt == null) {
58405847
return null;
58415848
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.alibaba.fastjson2.issues_1600;
2+
3+
import com.alibaba.fastjson2.JSON;
4+
import com.alibaba.fastjson2.JSONB;
5+
import com.alibaba.fastjson2.JSONObject;
6+
import com.alibaba.fastjson2.util.DateUtils;
7+
import org.junit.jupiter.api.Test;
8+
9+
import java.time.*;
10+
11+
import static org.junit.jupiter.api.Assertions.assertEquals;
12+
13+
public class Issue1620 {
14+
@Test
15+
public void test() {
16+
LocalDate localDate = LocalDate.of(2023, 7, 2);
17+
String str = "{\"value\":\"2023-07-02T16:00:00.000Z\"}";
18+
assertEquals(localDate, JSON.parseObject(str, Bean.class).value);
19+
assertEquals(localDate, JSON.parseObject(str.getBytes(), Bean.class).value);
20+
assertEquals(localDate, JSON.parseObject(str.toCharArray(), Bean.class).value);
21+
22+
assertEquals(localDate, JSONB.parseObject(JSONObject.parse(str).toJSONBBytes(), Bean.class).value);
23+
24+
LocalDateTime ldt = LocalDateTime.of(localDate, LocalTime.of(16, 0, 0));
25+
ZonedDateTime zdt = ZonedDateTime.of(ldt, DateUtils.OFFSET_8_ZONE_ID);
26+
Instant instant = zdt.toInstant();
27+
28+
assertEquals(
29+
localDate,
30+
JSONB.parseObject(
31+
JSONObject.of("value", ldt).toJSONBBytes(),
32+
Bean.class).value
33+
);
34+
assertEquals(
35+
localDate,
36+
JSONB.parseObject(
37+
JSONObject.of("value", zdt).toJSONBBytes(),
38+
Bean.class).value
39+
);
40+
41+
assertEquals(
42+
ldt,
43+
JSONB.parseObject(
44+
JSONObject.of("value", zdt).toJSONBBytes(),
45+
Bean1.class).value
46+
);
47+
48+
assertEquals(
49+
ZonedDateTime.of(LocalDateTime.of(localDate, LocalTime.MIN), DateUtils.DEFAULT_ZONE_ID),
50+
JSONB.parseObject(
51+
JSONObject.of("value", localDate).toJSONBBytes(),
52+
Bean2.class).value
53+
);
54+
assertEquals(
55+
ZonedDateTime.of(ldt, DateUtils.DEFAULT_ZONE_ID),
56+
JSONB.parseObject(
57+
JSONObject.of("value", ldt).toJSONBBytes(),
58+
Bean2.class).value
59+
);
60+
assertEquals(
61+
zdt.toInstant(),
62+
JSONB.parseObject(
63+
JSONObject.of("value", instant).toJSONBBytes(),
64+
Bean2.class).value.toInstant()
65+
);
66+
}
67+
68+
public static class Bean {
69+
public LocalDate value;
70+
}
71+
72+
public static class Bean1 {
73+
public LocalDateTime value;
74+
}
75+
76+
public static class Bean2 {
77+
public ZonedDateTime value;
78+
}
79+
80+
public static class Bean3 {
81+
public Instant value;
82+
}
83+
}

0 commit comments

Comments
 (0)