Skip to content

Commit

Permalink
bug fix for LocalDate JSONField format not work #380
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed May 30, 2022
1 parent 54aab3a commit 27a73b6
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public abstract class DateTimeCodec {

public final Locale locale;

public final boolean yyyyMMddhhmmss19;

DateTimeFormatter dateFormatter;

public DateTimeCodec(String format) {
Expand All @@ -28,6 +30,7 @@ public DateTimeCodec(String format, Locale locale) {

this.format = format;
this.locale = locale;
yyyyMMddhhmmss19 = "yyyy-MM-dd HH:mm:ss".equals(format);

boolean formatUnixTime = false, formatISO8601 = false, formatMillis = false, hasDay = false, hasHour = false;
if (format != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,14 @@ static ObjectWriter getObjectWriter(Type fieldType, Class fieldClass, String for
}
}

if (LocalDate.class.isAssignableFrom(valueClass)) {
if (format == null || format.isEmpty()) {
return ObjectWriterImplLocalDate.INSTANCE;
} else {
return new ObjectWriterImplLocalDate(format, locale);
}
}

if (Optional.class == valueClass) {
return ObjectWriterImplOptional.of(format, locale);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
package com.alibaba.fastjson2.writer;

import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.codec.DateTimeCodec;

import java.lang.reflect.Type;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

final class ObjectWriterImplLocalDate
extends ObjectWriterBaseModule.PrimitiveImpl {
static final ObjectWriterImplLocalDate INSTANCE = new ObjectWriterImplLocalDate();
extends DateTimeCodec
implements ObjectWriter {
static final ObjectWriterImplLocalDate INSTANCE = new ObjectWriterImplLocalDate(null, null);

final boolean yyyyMMdd10;

public ObjectWriterImplLocalDate(String format, Locale locale) {
super(format, locale);
yyyyMMdd10 = "yyyy-MM-dd".equals(format);
}

@Override
public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
Expand All @@ -25,24 +38,54 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f

LocalDate date = (LocalDate) object;

String dateFormat = ctx.getDateFormat();
if (dateFormat == null) {
if (formatUnixTime || ctx.isDateFormatUnixTime()) {
LocalDateTime dateTime = LocalDateTime.of(date, LocalTime.MIN);
long millis = dateTime.atZone(ctx.getZoneId())
.toInstant()
.toEpochMilli();
jsonWriter.writeInt64(millis / 1000);
return;
}

if (formatMillis || ctx.isDateFormatMillis()) {
LocalDateTime dateTime = LocalDateTime.of(date, LocalTime.MIN);
long millis = dateTime.atZone(ctx.getZoneId())
.toInstant()
.toEpochMilli();
jsonWriter.writeInt64(millis);
return;
}

if (yyyyMMdd10) {
jsonWriter.writeDateYYYMMDD10(
date.getYear(),
date.getMonthValue(),
date.getDayOfMonth());
} else {
String str;
if ("yyyy-MM-dd HH:mm:ss".equals(dateFormat)) {
jsonWriter.writeDateTime19(
date.getYear(),
date.getMonthValue(),
date.getDayOfMonth(), 0, 0, 0);
return;
}

str = ctx.getDateFormatter().format(date);
jsonWriter.writeString(str);
return;
}

if (yyyyMMddhhmmss19) {
jsonWriter.writeDateTime19(
date.getYear(),
date.getMonthValue(),
date.getDayOfMonth(), 0, 0, 0);
return;
}

DateTimeFormatter formatter = this.getDateFormatter();
if (formatter == null) {
formatter = ctx.getDateFormatter();
}

if (formatter == null) {
jsonWriter.writeDateYYYMMDD10(
date.getYear(),
date.getMonthValue(),
date.getDayOfMonth());
return;
}

String str = formatter.format(date);
jsonWriter.writeString(str);
}
}
61 changes: 61 additions & 0 deletions core/src/test/java/com/alibaba/fastjson2/issues/Issue380.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.alibaba.fastjson2.issues;

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

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;

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

public class Issue380 {
@Test
public void test() {
Bean bean = new Bean();
bean.date = LocalDate.of(2017, 6, 28);

assertEquals("{\"date\":\"2017-06-28 00:00:00\"}", JSON.toJSONString(bean));
assertEquals("{\"date\":\"2017-06-28 00:00:00\"}", JSON.toJSONString(bean, "yyyy-MM-dd"));
}

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

@Test
public void test1() {
Bean1 bean = new Bean1();
bean.date = LocalDateTime.of(2017, 6, 28, 11, 12, 13);

assertEquals("{\"date\":\"2017-06-28\"}", JSON.toJSONString(bean));
assertEquals("{\"date\":\"2017-06-28\"}", JSON.toJSONString(bean, "yyyy-MM-dd"));
}

public static class Bean1 {
@JSONField(format = "yyyy-MM-dd")
public LocalDateTime date;
}

@Test
public void test2() {
ZonedDateTime zdt = LocalDateTime.of(2017, 6, 28, 11, 12, 13)
.atZone(
ZoneId.of("Asia/Shanghai")
);
Bean2 bean = new Bean2();
bean.date = new Date(zdt.toInstant().toEpochMilli());

assertEquals("{\"date\":\"2017-06-28\"}", JSON.toJSONString(bean));
assertEquals("{\"date\":\"2017-06-28\"}", JSON.toJSONString(bean, "yyyy-MM-dd HH:mm:ss"));
}

public static class Bean2 {
@JSONField(format = "yyyy-MM-dd")
public java.util.Date date;
}
}

0 comments on commit 27a73b6

Please sign in to comment.