This is an automated email from the ASF dual-hosted git repository. nicholasjiang pushed a commit to branch branch-0.1 in repository https://gitbox.apache.org/repos/asf/paimon-webui.git
commit e55b3fb45b66c052a4046f8b185d45d01f52f7cd Author: XianmingZhou00 <147145809+xianmingzho...@users.noreply.github.com> AuthorDate: Thu Jul 11 11:24:32 2024 +0800 [Improvement] Unify global date format (#496) --- .../paimon/web/server/configrue/JacksonConfig.java | 27 +++++++- .../web/server/configurer/JacksonConfigTests.java | 73 ++++++++++++++++++++-- 2 files changed, 93 insertions(+), 7 deletions(-) diff --git a/paimon-web-server/src/main/java/org/apache/paimon/web/server/configrue/JacksonConfig.java b/paimon-web-server/src/main/java/org/apache/paimon/web/server/configrue/JacksonConfig.java index d2d8befb..a86038d8 100644 --- a/paimon-web-server/src/main/java/org/apache/paimon/web/server/configrue/JacksonConfig.java +++ b/paimon-web-server/src/main/java/org/apache/paimon/web/server/configrue/JacksonConfig.java @@ -24,17 +24,29 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.text.SimpleDateFormat; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.format.DateTimeFormatter; /** JacksonConfig. */ @Configuration public class JacksonConfig { + + public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + public static final String DATE_FORMAT = "yyyy-MM-dd"; + public static final String TIME_FORMAT = "HH:mm:ss"; + @Bean public ObjectMapper getJacksonObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); @@ -53,11 +65,22 @@ public class JacksonConfig { JavaTimeModule javaTimeModule = new JavaTimeModule(); javaTimeModule.addSerializer( LocalDateTime.class, - new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT))); javaTimeModule.addDeserializer( LocalDateTime.class, - new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT))); + javaTimeModule.addSerializer( + LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_FORMAT))); + javaTimeModule.addDeserializer( + LocalDate.class, + new LocalDateDeserializer(DateTimeFormatter.ofPattern(DATE_FORMAT))); + javaTimeModule.addSerializer( + LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(TIME_FORMAT))); + javaTimeModule.addDeserializer( + LocalTime.class, + new LocalTimeDeserializer(DateTimeFormatter.ofPattern(TIME_FORMAT))); objectMapper.registerModule(javaTimeModule); + objectMapper.setDateFormat(new SimpleDateFormat(DATE_TIME_FORMAT)); objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); return objectMapper; } diff --git a/paimon-web-server/src/test/java/org/apache/paimon/web/server/configurer/JacksonConfigTests.java b/paimon-web-server/src/test/java/org/apache/paimon/web/server/configurer/JacksonConfigTests.java index 4b27d882..4e1a675c 100644 --- a/paimon-web-server/src/test/java/org/apache/paimon/web/server/configurer/JacksonConfigTests.java +++ b/paimon-web-server/src/test/java/org/apache/paimon/web/server/configurer/JacksonConfigTests.java @@ -26,7 +26,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.io.IOException; +import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -37,20 +44,24 @@ public class JacksonConfigTests { @Autowired private ObjectMapper objectMapper; - private static final String TIME_FORMATTED_JSON_STR = "\"2024-06-26 13:01:30\""; - private static final String TIME_UNFORMATTED_JSON_STR = "\"2024-06-26T13:01:30Z\""; + private static final String DATE_TIME_FORMATTED_JSON_STR = "\"2024-06-26 13:01:30\""; + private static final String DATE_TIME_UNFORMATTED_JSON_STR = "\"2024-06-26T13:01:30Z\""; + private static final String DATE_FORMATTED_JSON_STR = "\"2024-06-26\""; + private static final String TIME_FORMATTED_JSON_STR = "\"13:01:30\""; + private static final String DATE_TIME_STR = "2024-06-26 13:01:30"; + private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; @Test public void testLocalDateTimeSerialization() throws IOException { LocalDateTime dateTime = LocalDateTime.of(2024, 6, 26, 13, 1, 30); String json = objectMapper.writeValueAsString(dateTime); - assertEquals(TIME_FORMATTED_JSON_STR, json); + assertEquals(DATE_TIME_FORMATTED_JSON_STR, json); } @Test public void testLocalDateTimeDeserialization() throws IOException { LocalDateTime dateTime = - objectMapper.readValue(TIME_FORMATTED_JSON_STR, LocalDateTime.class); + objectMapper.readValue(DATE_TIME_FORMATTED_JSON_STR, LocalDateTime.class); assertEquals(LocalDateTime.of(2024, 6, 26, 13, 1, 30), dateTime); } @@ -58,6 +69,58 @@ public class JacksonConfigTests { public void testInvalidLocalDateTimeDeserialization() { assertThrows( com.fasterxml.jackson.databind.exc.InvalidFormatException.class, - () -> objectMapper.readValue(TIME_UNFORMATTED_JSON_STR, LocalDateTime.class)); + () -> objectMapper.readValue(DATE_TIME_UNFORMATTED_JSON_STR, LocalDateTime.class)); + } + + @Test + public void testLocalDateSerialization() throws IOException { + LocalDate dateTime = LocalDate.of(2024, 6, 26); + String json = objectMapper.writeValueAsString(dateTime); + assertEquals(DATE_FORMATTED_JSON_STR, json); + } + + @Test + public void testLocalDateDeserialization() throws IOException { + LocalDate dateTime = objectMapper.readValue(DATE_FORMATTED_JSON_STR, LocalDate.class); + assertEquals(LocalDate.of(2024, 6, 26), dateTime); + } + + @Test + public void testLocalTimeSerialization() throws IOException { + LocalTime dateTime = LocalTime.of(13, 1, 30); + String json = objectMapper.writeValueAsString(dateTime); + assertEquals(TIME_FORMATTED_JSON_STR, json); + } + + @Test + public void testLocalTimeDeserialization() throws IOException { + LocalTime dateTime = objectMapper.readValue(TIME_FORMATTED_JSON_STR, LocalTime.class); + assertEquals(LocalTime.of(13, 1, 30), dateTime); + } + + @Test + public void testDateSerialization() throws IOException { + Date date = parseDate(DATE_TIME_STR); + String json = objectMapper.writeValueAsString(date); + assertEquals(DATE_TIME_FORMATTED_JSON_STR, json); + } + + @Test + public void testDateDeserialization() throws IOException { + Date date = parseDate(DATE_TIME_STR); + Date dateDeserialized = objectMapper.readValue(DATE_TIME_FORMATTED_JSON_STR, Date.class); + assertEquals(dateDeserialized, date); + } + + private Date parseDate(String date) { + DateTimeFormatter formatter = + DateTimeFormatter.ofPattern(JacksonConfigTests.DATE_TIME_PATTERN); + + LocalDateTime localDateTime = LocalDateTime.parse(date, formatter); + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId); + + Instant instant = zonedDateTime.toInstant(); + return Date.from(instant); } }