Skip to content

Commit

Permalink
LocalDateTime & LocalDate parse support more cases
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Aug 10, 2024
1 parent 239795a commit 191c8c2
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 0 deletions.
23 changes: 23 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java
Original file line number Diff line number Diff line change
Expand Up @@ -4946,6 +4946,29 @@ public final LocalDate readLocalDate() {
}
}
}

int nextQuoteOffset = -1;
for (int i = offset, end = Math.min(i + 17, this.end); i < end; ++i) {
if (chars[i] == quote) {
nextQuoteOffset = i;
}
}
if (nextQuoteOffset != -1
&& nextQuoteOffset - offset > 10
&& chars[nextQuoteOffset - 6] == '-'
&& chars[nextQuoteOffset - 3] == '-'
) {
int year = TypeUtils.parseInt(chars, offset, nextQuoteOffset - offset - 6);
int month = TypeUtils.parseInt(chars, nextQuoteOffset - 5, 2);
int dayOfMonth = TypeUtils.parseInt(chars, nextQuoteOffset - 2, 2);
LocalDate localDate = LocalDate.of(year, month, dayOfMonth);
this.offset = nextQuoteOffset + 1;
next();
if (comma = (this.ch == ',')) {
next();
}
return localDate;
}
}
}
return super.readLocalDate();
Expand Down
23 changes: 23 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java
Original file line number Diff line number Diff line change
Expand Up @@ -6048,6 +6048,29 @@ public final LocalDate readLocalDate() {
}
}
}

int nextQuoteOffset = -1;
for (int i = offset, end = Math.min(i + 17, this.end); i < end; ++i) {
if (bytes[i] == quote) {
nextQuoteOffset = i;
}
}
if (nextQuoteOffset != -1
&& nextQuoteOffset - offset > 10
&& bytes[nextQuoteOffset - 6] == '-'
&& bytes[nextQuoteOffset - 3] == '-'
) {
int year = TypeUtils.parseInt(bytes, offset, nextQuoteOffset - offset - 6);
int month = TypeUtils.parseInt(bytes, nextQuoteOffset - 5, 2);
int dayOfMonth = TypeUtils.parseInt(bytes, nextQuoteOffset - 2, 2);
LocalDate localDate = LocalDate.of(year, month, dayOfMonth);
this.offset = nextQuoteOffset + 1;
next();
if (comma = (this.ch == ',')) {
next();
}
return localDate;
}
}
}
return super.readLocalDate();
Expand Down
20 changes: 20 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/util/DateUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5900,6 +5900,16 @@ public static LocalDateTime parseLocalDateTimeX(char[] str, int offset, int len)
S6 = c26;
S7 = c27;
S8 = c28;
} else if (str[offset + len - 15] == '-' && str[offset + len - 12] == '-'
&& (str[offset + len - 9] == ' ' || str[offset + len - 9] == 'T')
&& str[offset + len - 6] == ':' && str[offset + len - 3] == ':') {
int year = TypeUtils.parseInt(str, offset, len - 15);
int month = TypeUtils.parseInt(str, offset + len - 14, 2);
int dayOfMonth = TypeUtils.parseInt(str, offset + len - 11, 2);
int hour = TypeUtils.parseInt(str, offset + len - 8, 2);
int minute = TypeUtils.parseInt(str, offset + len - 5, 2);
int second = TypeUtils.parseInt(str, offset + len - 2, 2);
return LocalDateTime.of(year, month, dayOfMonth, hour, minute, second);
} else {
return null;
}
Expand Down Expand Up @@ -6034,6 +6044,16 @@ public static LocalDateTime parseLocalDateTimeX(byte[] str, int offset, int len)
S6 = c26;
S7 = c27;
S8 = c28;
} else if (str[offset + len - 15] == '-' && str[offset + len - 12] == '-'
&& (str[offset + len - 9] == ' ' || str[offset + len - 9] == 'T')
&& str[offset + len - 6] == ':' && str[offset + len - 3] == ':') {
int year = TypeUtils.parseInt(str, offset, len - 15);
int month = TypeUtils.parseInt(str, offset + len - 14, 2);
int dayOfMonth = TypeUtils.parseInt(str, offset + len - 11, 2);
int hour = TypeUtils.parseInt(str, offset + len - 8, 2);
int minute = TypeUtils.parseInt(str, offset + len - 5, 2);
int second = TypeUtils.parseInt(str, offset + len - 2, 2);
return LocalDateTime.of(year, month, dayOfMonth, hour, minute, second);
} else {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.alibaba.fastjson2.issues_2800;

import com.alibaba.fastjson2.JSON;
import org.junit.jupiter.api.Test;

import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Issue2859 {
@Test
public void test() {
String str = "{\"time\":\"-999999999-11-12 13:14:15\"}";
{
Bean bean = JSON.parseObject(str, Bean.class);
assertEquals(str, JSON.toJSONString(bean));
}
{
Bean bean = JSON.parseObject(str.getBytes(StandardCharsets.UTF_8), Bean.class);
assertEquals(str, JSON.toJSONString(bean));
}
{
Bean bean = JSON.parseObject(str.toCharArray(), Bean.class);
assertEquals(str, JSON.toJSONString(bean));
}
}

static class Bean {
public LocalDateTime time;
}

@Test
public void test1() {
String str = "{\"date\":\"-999999999-11-12\"}";
{
Bean1 bean = JSON.parseObject(str, Bean1.class);
assertEquals(str, JSON.toJSONString(bean));
}
{
Bean1 bean = JSON.parseObject(str.getBytes(StandardCharsets.UTF_8), Bean1.class);
assertEquals(str, JSON.toJSONString(bean));
}
{
Bean1 bean = JSON.parseObject(str.toCharArray(), Bean1.class);
assertEquals(str, JSON.toJSONString(bean));
}
}

static class Bean1 {
public LocalDate date;
}
}

0 comments on commit 191c8c2

Please sign in to comment.