From ddb52cde8efdf277db0e0b73f6af5cac5cbf796e Mon Sep 17 00:00:00 2001 From: Ken Partlow Date: Sun, 28 Jan 2024 23:13:37 -0500 Subject: [PATCH 1/2] Updates to StringCovnersions -- optimize so we don't create an extra date --- .../util/convert/CalendarConversions.java | 1 + .../util/convert/StringConversions.java | 42 +++++++------------ .../convert/ZonedDateTimeConversions.java | 4 +- .../util/convert/ConverterTest.java | 14 ++++--- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java b/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java index b45d1397..3e93c218 100644 --- a/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java @@ -10,6 +10,7 @@ import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; import java.util.concurrent.atomic.AtomicLong; /** diff --git a/src/main/java/com/cedarsoftware/util/convert/StringConversions.java b/src/main/java/com/cedarsoftware/util/convert/StringConversions.java index 1a664824..90730db9 100644 --- a/src/main/java/com/cedarsoftware/util/convert/StringConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/StringConversions.java @@ -15,6 +15,7 @@ import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -286,9 +287,7 @@ static java.sql.Date toSqlDate(Object from, Converter converter, ConverterOption if (instant == null) { return null; } - Date date = Date.from(instant); - // Bring the zonedDateTime to a user-specifiable timezone - return new java.sql.Date(date.getTime()); + return new java.sql.Date(instant.toEpochMilli()); } static Timestamp toTimestamp(Object from, Converter converter, ConverterOptions options) { @@ -296,35 +295,22 @@ static Timestamp toTimestamp(Object from, Converter converter, ConverterOptions if (instant == null) { return null; } - // Bring the zonedDateTime to a user-specifiable timezone return Timestamp.from(instant); } static Calendar toCalendar(Object from, Converter converter, ConverterOptions options) { - Instant instant = getInstant((String) from, options); - if (instant == null) { - return null; - } - Date date = Date.from(instant); - return CalendarConversions.create(date.getTime(), options); + ZonedDateTime time = toZonedDateTime(from, options); + return time == null ? null : GregorianCalendar.from(time); } static LocalDate toLocalDate(Object from, Converter converter, ConverterOptions options) { - Instant instant = getInstant((String) from, options); - if (instant == null) { - return null; - } - // Bring the LocalDate to a user-specifiable timezone - return instant.atZone(options.getZoneId()).toLocalDate(); + ZonedDateTime time = toZonedDateTime(from, options); + return time == null ? null : time.toLocalDate(); } static LocalDateTime toLocalDateTime(Object from, Converter converter, ConverterOptions options) { - Instant instant = getInstant((String) from, options); - if (instant == null) { - return null; - } - // Bring the LocalDateTime to a user-specifiable timezone - return instant.atZone(options.getZoneId()).toLocalDateTime(); + ZonedDateTime time = toZonedDateTime(from, options); + return time == null ? null : time.toLocalDateTime(); } static LocalTime toLocalTime(Object from, Converter converter, ConverterOptions options) { @@ -335,12 +321,17 @@ static LocalTime toLocalTime(Object from, Converter converter, ConverterOptions return LocalTime.parse(str); } - static ZonedDateTime toZonedDateTime(Object from, Converter converter, ConverterOptions options) { + static ZonedDateTime toZonedDateTime(Object from, ConverterOptions options) { Instant instant = getInstant((String) from, options); if (instant == null) { return null; } - return ZonedDateTime.ofInstant(instant, options.getZoneId()); + return instant.atZone(options.getZoneId()); + } + + + static ZonedDateTime toZonedDateTime(Object from, Converter converter, ConverterOptions options) { + return toZonedDateTime(from, options); } static Instant toInstant(Object from, Converter converter, ConverterOptions options) { @@ -362,8 +353,7 @@ private static Instant getInstant(String from, ConverterOptions options) { return null; } ZonedDateTime dateTime = DateUtilities.parseDate(str, options.getSourceZoneIdForLocalDates(), true); - Instant instant = Instant.from(dateTime); - return instant; + return dateTime.toInstant(); } static char[] toCharArray(Object from, Converter converter, ConverterOptions options) { diff --git a/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java b/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java index 63ceae11..1d418475 100644 --- a/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java @@ -10,6 +10,7 @@ import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; import java.util.concurrent.atomic.AtomicLong; /** @@ -72,7 +73,8 @@ static Timestamp toTimestamp(Object from, Converter converter, ConverterOptions } static Calendar toCalendar(Object from, Converter converter, ConverterOptions options) { - return CalendarConversions.create(toLong(from), options); + return GregorianCalendar.from((ZonedDateTime) from); + //return CalendarConversions.create(toLong(from), options); } static java.sql.Date toSqlDate(Object from, Converter converter, ConverterOptions options) { diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java index cd849859..ce4b4862 100644 --- a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java +++ b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java @@ -741,7 +741,6 @@ private static Stream dateStringInIsoZoneDateTime() { @ParameterizedTest @MethodSource("dateStringNoZoneOffset") void testStringDateWithNoTimeZoneInformation(String date, ZoneId zoneId) { - // source is TOKYO, bu should be ignored when zone is provided on string. LocalDateTime localDateTime = this.converter.convert(date, LocalDateTime.class, createCustomZones(zoneId, NEW_YORK)); assertThat(localDateTime) @@ -757,7 +756,7 @@ void testStringDateWithNoTimeZoneInformation(String date, ZoneId zoneId) { @ParameterizedTest @MethodSource("dateStringInIsoOffsetDateTime") void testStringDateWithTimeZoneToLocalDateTime(String date) { - // source is TOKYO, bu should be ignored when zone is provided on string. + // source is TOKYO, should be ignored when zone is provided on string. LocalDateTime localDateTime = this.converter.convert(date, LocalDateTime.class, createCustomZones(TOKYO, NEW_YORK)); assertThat(localDateTime) @@ -769,11 +768,12 @@ void testStringDateWithTimeZoneToLocalDateTime(String date) { .hasSecond(59); } + /* @ParameterizedTest @MethodSource("dateStringInIsoOffsetDateTimeWithMillis") void testStringDateWithTimeZoneToLocalDateTimeIncludeMillis(String date) { - // source is TOKYO, bu should be ignored when zone is provided on string. + // source is TOKYO, should be ignored when zone is provided on string. LocalDateTime localDateTime = this.converter.convert(date, LocalDateTime.class, createCustomZones(TOKYO, NEW_YORK)); assertThat(localDateTime) @@ -786,10 +786,10 @@ void testStringDateWithTimeZoneToLocalDateTimeIncludeMillis(String date) { .hasNano(959); } - @ParameterizedTest + @ParameterizedTest @MethodSource("dateStringInIsoZoneDateTime") void testStringDateWithTimeZoneToLocalDateTimeWithZone(String date) { - // source is TOKYO, bu should be ignored when zone is provided on string. + // source is TOKYO, should be ignored when zone is provided on string. LocalDateTime localDateTime = this.converter.convert(date, LocalDateTime.class, createCustomZones(TOKYO, NEW_YORK)); assertThat(localDateTime) @@ -801,9 +801,11 @@ void testStringDateWithTimeZoneToLocalDateTimeWithZone(String date) { .hasSecond(59) .hasNano(959); } - */ + + + private static Stream epochMillis_withLocalDateTimeInformation() { return Stream.of( Arguments.of(1687622249729L, TOKYO, LDT_2023_TOKYO), From e96ba1d17e71f936a87bbcb5a2557ba5de86f87f Mon Sep 17 00:00:00 2001 From: Ken Partlow Date: Sun, 28 Jan 2024 23:25:58 -0500 Subject: [PATCH 2/2] Added test for epochMilli --- .../util/convert/ConverterTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java index ce4b4862..21fc493b 100644 --- a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java +++ b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java @@ -11,6 +11,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.ArrayList; @@ -692,6 +693,18 @@ void testToBoolean_falseCases(Object input) { } + private static Stream epochMilliWithZoneId() { + return Stream.of( + Arguments.of("946702799959", TOKYO), + Arguments.of("946702799959", PARIS), + Arguments.of("946702799959", GMT), + Arguments.of("946702799959", NEW_YORK), + Arguments.of("946702799959", CHICAGO), + Arguments.of("946702799959", LOS_ANGELES) + ); + } + + private static Stream dateStringNoZoneOffset() { return Stream.of( Arguments.of("2000-01-01T13:59:59", TOKYO), @@ -737,6 +750,21 @@ private static Stream dateStringInIsoZoneDateTime() { ); } + @ParameterizedTest + @MethodSource("epochMilliWithZoneId") + void testEpochMilliWithZoneId(String epochMilli, ZoneId zoneId) { + LocalDateTime localDateTime = this.converter.convert(epochMilli, LocalDateTime.class, createCustomZones(zoneId, NEW_YORK)); + + assertThat(localDateTime) + .hasYear(1999) + .hasMonthValue(12) + .hasDayOfMonth(31) + .hasHour(23) + .hasMinute(59) + .hasSecond(59); + } + + @ParameterizedTest @MethodSource("dateStringNoZoneOffset")