From c1d331ac638b8196bc84f896ed358b17d2e6ee63 Mon Sep 17 00:00:00 2001 From: Pavel_Bortnik Date: Mon, 12 Aug 2024 14:44:17 +0300 Subject: [PATCH 1/3] EPMRPP-93396 || Add more date time formatters --- .../databind/MultiFormatDateDeserializer.java | 31 +++++++++++++------ .../MultiFormatDateDeserializerTest.java | 1 + 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java index 9b86820..8dcd574 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java @@ -25,7 +25,8 @@ import java.time.ZoneId; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeFormatterBuilder; +import java.util.ArrayList; +import java.util.List; /** * Deserialization class for parsing incoming dates of different formats. @@ -40,6 +41,9 @@ public class MultiFormatDateDeserializer extends JsonDeserializer { private static final DateTimeFormatter LOCAL_DATE_TIME_MS_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS").withZone(ZoneId.of("UTC")); + private static final DateTimeFormatter LOCAL_DATE_TIME_MS_FORMAT_DATE = + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXX").withZone(ZoneId.of("UTC")); + @Override public Instant deserialize(JsonParser parser, DeserializationContext context) throws IOException { try { @@ -59,16 +63,23 @@ public Instant deserialize(JsonParser parser, DeserializationContext context) th } String strDate = parser.getText(); - DateTimeFormatter formatter = - new DateTimeFormatterBuilder().appendOptional(DateTimeFormatter.RFC_1123_DATE_TIME) - .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME) - .appendOptional(DateTimeFormatter.ISO_DATE_TIME) - .appendOptional(DateTimeFormatter.ISO_LOCAL_DATE_TIME) - .appendOptional(TIMESTAMP_FORMAT) - .appendOptional(LOCAL_DATE_TIME_MS_FORMAT) - .toFormatter(); - return LocalDateTime.from(formatter.parse(strDate)).toInstant(ZoneOffset.UTC); + List formatters = new ArrayList<>(); + formatters.add(DateTimeFormatter.RFC_1123_DATE_TIME); + formatters.add(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + formatters.add(DateTimeFormatter.ISO_DATE_TIME); + formatters.add(DateTimeFormatter.ISO_LOCAL_DATE_TIME); + formatters.add(TIMESTAMP_FORMAT); + formatters.add(LOCAL_DATE_TIME_MS_FORMAT); + formatters.add(LOCAL_DATE_TIME_MS_FORMAT_DATE); + for (DateTimeFormatter formatter : formatters) { + try { + return LocalDateTime.from(formatter.parse(strDate)).toInstant(ZoneOffset.UTC); + } catch (Exception e) { + //ignore + } + } + throw new RuntimeException(); } } diff --git a/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java b/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java index 81a70a7..a014278 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java @@ -48,6 +48,7 @@ class MultiFormatDateDeserializerTest { "2024-03-01T20:24:09.930Z", "2024-03-01T20:24:09.930", "2024-03-01T20:24:09.930+00:00", + "2024-03-01T20:24:09.930+0300", "1709324649930" }) void deserializeDates(String strDate) throws IOException { From 73d643de93bbf02d5b312e1b46ff73ed7286bd17 Mon Sep 17 00:00:00 2001 From: Pavel_Bortnik Date: Mon, 12 Aug 2024 18:33:52 +0300 Subject: [PATCH 2/3] EPMRPP-93396 || Add zones to date time formatter --- .../reporting/databind/MultiFormatDateDeserializer.java | 8 ++++++-- .../deserializers/MultiFormatDateDeserializerTest.java | 5 +++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java index 8dcd574..cee52d4 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java @@ -24,6 +24,7 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; +import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -75,9 +76,12 @@ public Instant deserialize(JsonParser parser, DeserializationContext context) th for (DateTimeFormatter formatter : formatters) { try { - return LocalDateTime.from(formatter.parse(strDate)).toInstant(ZoneOffset.UTC); + return ZonedDateTime.from(formatter.parse(strDate)).toInstant(); } catch (Exception e) { - //ignore + try { + return LocalDateTime.from(formatter.parse(strDate)).toInstant(ZoneOffset.UTC); + } catch (Exception ex) { + } } } throw new RuntimeException(); diff --git a/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java b/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java index a014278..5f81555 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java @@ -26,6 +26,7 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -44,11 +45,11 @@ class MultiFormatDateDeserializerTest { @ParameterizedTest @ValueSource(strings = { "2024-03-01T20:24:09.930987Z", - "2024-03-01T20:24:09.930987654Z", + "2024-03-01T20:24:09.930987654", "2024-03-01T20:24:09.930Z", "2024-03-01T20:24:09.930", "2024-03-01T20:24:09.930+00:00", - "2024-03-01T20:24:09.930+0300", + "2024-03-01T23:24:09.930+0300", "1709324649930" }) void deserializeDates(String strDate) throws IOException { From 4ada7628ab1404ac6359808eab1b1279715b25f4 Mon Sep 17 00:00:00 2001 From: Pavel_Bortnik Date: Mon, 19 Aug 2024 16:26:31 +0300 Subject: [PATCH 3/3] EPMRPP-93396 || Refactor MultiFormatDateDeserializer --- .../databind/MultiFormatDateDeserializer.java | 44 ++++++++++--------- .../MultiFormatDateDeserializerTest.java | 1 + 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java index cee52d4..1765d57 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java @@ -26,7 +26,9 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; +import java.time.format.DateTimeParseException; +import java.time.temporal.TemporalAccessor; +import java.util.Arrays; import java.util.List; /** @@ -40,10 +42,20 @@ public class MultiFormatDateDeserializer extends JsonDeserializer { DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("UTC")); private static final DateTimeFormatter LOCAL_DATE_TIME_MS_FORMAT = - DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS").withZone(ZoneId.of("UTC")); + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS"); private static final DateTimeFormatter LOCAL_DATE_TIME_MS_FORMAT_DATE = - DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXX").withZone(ZoneId.of("UTC")); + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXX"); + + private static final List PREDEFINED_FORMATS = Arrays.asList( + DateTimeFormatter.RFC_1123_DATE_TIME, + DateTimeFormatter.ISO_OFFSET_DATE_TIME, + DateTimeFormatter.ISO_DATE_TIME, + DateTimeFormatter.ISO_LOCAL_DATE_TIME, + TIMESTAMP_FORMAT, + LOCAL_DATE_TIME_MS_FORMAT, + LOCAL_DATE_TIME_MS_FORMAT_DATE + ); @Override public Instant deserialize(JsonParser parser, DeserializationContext context) throws IOException { @@ -52,7 +64,6 @@ public Instant deserialize(JsonParser parser, DeserializationContext context) th if (parser.getText() == null) { return Instant.ofEpochMilli(longDate); } - // ignore } catch (Exception e) { // ignore } @@ -65,25 +76,16 @@ public Instant deserialize(JsonParser parser, DeserializationContext context) th String strDate = parser.getText(); - List formatters = new ArrayList<>(); - formatters.add(DateTimeFormatter.RFC_1123_DATE_TIME); - formatters.add(DateTimeFormatter.ISO_OFFSET_DATE_TIME); - formatters.add(DateTimeFormatter.ISO_DATE_TIME); - formatters.add(DateTimeFormatter.ISO_LOCAL_DATE_TIME); - formatters.add(TIMESTAMP_FORMAT); - formatters.add(LOCAL_DATE_TIME_MS_FORMAT); - formatters.add(LOCAL_DATE_TIME_MS_FORMAT_DATE); - - for (DateTimeFormatter formatter : formatters) { + for (DateTimeFormatter formatter : PREDEFINED_FORMATS) { try { - return ZonedDateTime.from(formatter.parse(strDate)).toInstant(); - } catch (Exception e) { - try { - return LocalDateTime.from(formatter.parse(strDate)).toInstant(ZoneOffset.UTC); - } catch (Exception ex) { - } + TemporalAccessor parsedDate = formatter.parseBest(strDate, ZonedDateTime::from, + LocalDateTime::from); + return parsedDate instanceof ZonedDateTime ? ((ZonedDateTime) parsedDate).toInstant() + : ((LocalDateTime) parsedDate).toInstant(ZoneOffset.UTC); + } catch (DateTimeParseException e) { + // Exception means the text could not be parsed with this formatter, continue with next formatter } } - throw new RuntimeException(); + throw new IOException("Unable to parse date: " + strDate); } } diff --git a/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java b/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java index 5f81555..a47fafd 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java @@ -49,6 +49,7 @@ class MultiFormatDateDeserializerTest { "2024-03-01T20:24:09.930Z", "2024-03-01T20:24:09.930", "2024-03-01T20:24:09.930+00:00", + "2024-03-01T19:24:09.930-01:00", "2024-03-01T23:24:09.930+0300", "1709324649930" })