Skip to content

Commit

Permalink
improved LocalTime parse support, fix issue #591
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Jul 28, 2022
1 parent 419a2a3 commit 6ed9a16
Show file tree
Hide file tree
Showing 9 changed files with 296 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
public class EishayCodecOnlyJSONBTest {
public static void main(String[] args) throws RunnerException {
EishayCodecOnlyJSONB benchmark = new EishayCodecOnlyJSONB();
// benchmark.serialize_jsonb_arrayMapping_perf_test();
benchmark.deserialize_jsonbArrayMapping_perf_test();
benchmark.serialize_jsonb_arrayMapping_perf_test();
// benchmark.deserialize_jsonbArrayMapping_perf_test();
}
}
4 changes: 4 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,8 @@ public LocalTime readLocalTime() {

int len = getStringLength();
switch (len) {
case 5:
return readLocalTime5();
case 8:
return readLocalTime8();
case 10:
Expand Down Expand Up @@ -1197,6 +1199,8 @@ public long readMillisFromString() {

protected abstract LocalDateTime readLocalDateTimeX(int len);

protected abstract LocalTime readLocalTime5();

protected abstract LocalTime readLocalTime8();

protected abstract LocalTime readLocalTime10();
Expand Down
46 changes: 46 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONReaderJSONB.java
Original file line number Diff line number Diff line change
Expand Up @@ -4273,6 +4273,52 @@ protected LocalDateTime readLocalDate10() {
return ldt;
}

@Override
protected LocalTime readLocalTime5() {
type = bytes[offset];
if (type != BC_STR_ASCII_FIX_MIN + 5) {
throw new JSONException("date only support string input");
}

byte c0 = bytes[offset + 1];
byte c1 = bytes[offset + 2];
byte c2 = bytes[offset + 3];
byte c3 = bytes[offset + 4];
byte c4 = bytes[offset + 5];

byte h0, h1, i0, i1, s0, s1;
if (c2 == ':') {
h0 = c0;
h1 = c1;
i0 = c3;
i1 = c4;
} else {
return null;
}

int hour;
if (h0 >= '0' && h0 <= '9'
&& h1 >= '0' && h1 <= '9'
) {
hour = (h0 - '0') * 10 + (h1 - '0');
} else {
return null;
}

int minute;
if (i0 >= '0' && i0 <= '9'
&& i1 >= '0' && i1 <= '9'
) {
minute = (i0 - '0') * 10 + (i1 - '0');
} else {
return null;
}

offset += 6;

return LocalTime.of(hour, minute);
}

@Override
protected LocalTime readLocalTime8() {
type = bytes[offset];
Expand Down
50 changes: 50 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONReaderStr.java
Original file line number Diff line number Diff line change
Expand Up @@ -3433,6 +3433,56 @@ protected LocalDateTime readLocalDateTime18() {
return ldt;
}

@Override
protected LocalTime readLocalTime5() {
if (ch != '"' && ch != '\'') {
throw new JSONException("localTime only support string input");
}

char c0 = str.charAt(offset + 0);
char c1 = str.charAt(offset + 1);
char c2 = str.charAt(offset + 2);
char c3 = str.charAt(offset + 3);
char c4 = str.charAt(offset + 4);

char h0, h1, i0, i1;
if (c2 == ':') {
h0 = c0;
h1 = c1;
i0 = c3;
i1 = c4;
} else {
return null;
}

int hour;
if (h0 >= '0' && h0 <= '9'
&& h1 >= '0' && h1 <= '9'
) {
hour = (h0 - '0') * 10 + (h1 - '0');
} else {
return null;
}

int minute;
if (i0 >= '0' && i0 <= '9'
&& i1 >= '0' && i1 <= '9'
) {
minute = (i0 - '0') * 10 + (i1 - '0');
} else {
return null;
}

offset += 6;
next();
if (ch == ',') {
this.comma = true;
next();
}

return LocalTime.of(hour, minute, 0);
}

@Override
protected LocalTime readLocalTime8() {
if (ch != '"' && ch != '\'') {
Expand Down
50 changes: 50 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java
Original file line number Diff line number Diff line change
Expand Up @@ -3869,6 +3869,56 @@ protected LocalDateTime readLocalDateTime18() {
return ldt;
}

@Override
protected LocalTime readLocalTime5() {
if (ch != '"' && ch != '\'') {
throw new JSONException("localTime only support string input");
}

char c0 = chars[offset];
char c1 = chars[offset + 1];
char c2 = chars[offset + 2];
char c3 = chars[offset + 3];
char c4 = chars[offset + 4];

char h0, h1, i0, i1;
if (c2 == ':') {
h0 = c0;
h1 = c1;
i0 = c3;
i1 = c4;
} else {
return null;
}

int hour;
if (h0 >= '0' && h0 <= '9'
&& h1 >= '0' && h1 <= '9'
) {
hour = (h0 - '0') * 10 + (h1 - '0');
} else {
return null;
}

int minute;
if (i0 >= '0' && i0 <= '9'
&& i1 >= '0' && i1 <= '9'
) {
minute = (i0 - '0') * 10 + (i1 - '0');
} else {
return null;
}

offset += 6;
next();
if (ch == ',') {
this.comma = true;
next();
}

return LocalTime.of(hour, minute);
}

@Override
protected LocalTime readLocalTime8() {
if (ch != '"' && ch != '\'') {
Expand Down
50 changes: 50 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java
Original file line number Diff line number Diff line change
Expand Up @@ -4596,6 +4596,56 @@ protected LocalDateTime readLocalDateTime17() {
return ldt;
}

@Override
protected LocalTime readLocalTime5() {
if (ch != '"' && ch != '\'') {
throw new JSONException("localTime only support string input");
}

byte c0 = bytes[offset + 0];
byte c1 = bytes[offset + 1];
byte c2 = bytes[offset + 2];
byte c3 = bytes[offset + 3];
byte c4 = bytes[offset + 4];

byte h0, h1, i0, i1;
if (c2 == ':') {
h0 = c0;
h1 = c1;
i0 = c3;
i1 = c4;
} else {
return null;
}

int hour;
if (h0 >= '0' && h0 <= '9'
&& h1 >= '0' && h1 <= '9'
) {
hour = (h0 - '0') * 10 + (h1 - '0');
} else {
return null;
}

int minute;
if (i0 >= '0' && i0 <= '9'
&& i1 >= '0' && i1 <= '9'
) {
minute = (i0 - '0') * 10 + (i1 - '0');
} else {
return null;
}

offset += 6;
next();
if (ch == ',') {
this.comma = true;
next();
}

return LocalTime.of(hour, minute);
}

@Override
protected LocalTime readLocalTime8() {
if (ch != '"' && ch != '\'') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,16 @@ public ObjectReader getFieldObjectReader(JSONReader.Context context) {

@Override
public ObjectReader getObjectReader(JSONReader jsonReader) {
if (fieldObjectReader == null) {
fieldObjectReader = jsonReader
.getObjectReader(fieldType);
if (fieldObjectReader != null) {
return fieldObjectReader;
}
return fieldObjectReader;

ObjectReader formattedObjectReader = FieldReaderObject.createFormattedObjectReader(fieldType, fieldClass, format, null);
if (formattedObjectReader != null) {
return fieldObjectReader = formattedObjectReader;
}

return fieldObjectReader = jsonReader.getObjectReader(fieldType);
}

@Override
Expand Down Expand Up @@ -130,9 +135,7 @@ public void readFieldValue(JSONReader jsonReader, T object) {
@Override
public Object readFieldValue(JSONReader jsonReader) {
if (fieldObjectReader == null) {
fieldObjectReader = jsonReader
.getContext()
.getObjectReader(fieldType);
fieldObjectReader = getObjectReader(jsonReader);
}

return jsonReader.isJSONB()
Expand Down
42 changes: 42 additions & 0 deletions core/src/test/java/com/alibaba/fastjson2/date/LocalTimeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,46 @@ public static class Bean2 {
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
public LocalTime time;
}

@Test
public void test3() {
Bean3 bean = new Bean3();
bean.time = LocalTime.of(12, 13, 0);
String str = JSON.toJSONString(bean, "yyyy-MM-dd HH:mm:ss");
assertEquals("{\"time\":\"12:13\"}", str);
Bean3 bean1 = JSON.parseObject(str, Bean3.class);
assertEquals(bean.time.getHour(), bean1.time.getHour());
assertEquals(bean.time.getMinute(), bean1.time.getMinute());
assertEquals(bean.time.getSecond(), bean1.time.getSecond());
}

public static class Bean3 {
@JSONField(format = "HH:mm")
public LocalTime time;
}

@Test
public void test4() {
Bean4 bean = new Bean4();
bean.time = LocalTime.of(12, 13, 0);
String str = JSON.toJSONString(bean, "yyyy-MM-dd HH:mm:ss");
assertEquals("{\"time\":\"12:13\"}", str);
Bean4 bean1 = JSON.parseObject(str, Bean4.class);
assertEquals(bean.time.getHour(), bean1.time.getHour());
assertEquals(bean.time.getMinute(), bean1.time.getMinute());
assertEquals(bean.time.getSecond(), bean1.time.getSecond());
}

public static class Bean4 {
@JSONField(format = "HH:mm")
private LocalTime time;

public LocalTime getTime() {
return time;
}

public void setTime(LocalTime time) {
this.time = time;
}
}
}
42 changes: 42 additions & 0 deletions core/src/test/java/com/alibaba/fastjson2/issues/Issue591.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.alibaba.fastjson2.issues;

import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import org.junit.jupiter.api.Test;

import java.time.LocalTime;

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

public class Issue591 {
@Test
void test2() {
String testStr = "{\"time\": \"09:00\", \"nest\": {\"time\": \"09:00\"}, \"nests\": [{\"time\": \"09:00\"}]}";

TestAA aa = JSONObject.parseObject(testStr, TestAA.class);
assertNotNull(aa);
assertNotNull(aa.time);
assertNotNull(aa.nest.time);
}

@Data
public class TestAA {
private LocalTime time;
private TestBB nest;
// private List<TestBB> nests;
}

public class TestBB {
@JSONField(name = "time", format = "HH:mm")
private LocalTime time;

public LocalTime getTime() {
return time;
}

public void setTime(LocalTime time) {
this.time = time;
}
}
}

0 comments on commit 6ed9a16

Please sign in to comment.