From 7c890ccd9214e98e7121c4d9318479f3607eefd3 Mon Sep 17 00:00:00 2001 From: John DeRegnaucourt Date: Sat, 3 Feb 2024 12:46:42 -0500 Subject: [PATCH] Added in Number and Map support for year. More robust support for MonthDay and Year (allowing extraction from date-time strings). Fixed misspellings. --- .../cedarsoftware/util/convert/Converter.java | 24 +++------------ .../util/convert/MapConversions.java | 5 ++++ .../util/convert/NumberConversions.java | 9 ++++++ .../util/convert/StringConversions.java | 23 +++++++++++--- .../util/convert/ConverterTest.java | 30 +++++++------------ .../util/convert/DateConversionTests.java | 5 ---- 6 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/cedarsoftware/util/convert/Converter.java b/src/main/java/com/cedarsoftware/util/convert/Converter.java index 70205b5f..aff236ca 100644 --- a/src/main/java/com/cedarsoftware/util/convert/Converter.java +++ b/src/main/java/com/cedarsoftware/util/convert/Converter.java @@ -161,7 +161,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(String.class, Integer.class), StringConversions::toInt); DEFAULT_FACTORY.put(pair(Year.class, Integer.class), YearConversions::toInt); - // toLong DEFAULT_FACTORY.put(pair(Void.class, long.class), NumberConversions::toLongZero); DEFAULT_FACTORY.put(pair(Void.class, Long.class), VoidConversions::toNull); @@ -192,7 +191,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(OffsetDateTime.class, Long.class), OffsetDateTimeConversions::toLong); DEFAULT_FACTORY.put(pair(Year.class, Long.class), YearConversions::toLong); - // toFloat DEFAULT_FACTORY.put(pair(Void.class, float.class), NumberConversions::toFloatZero); DEFAULT_FACTORY.put(pair(Void.class, Float.class), VoidConversions::toNull); @@ -244,7 +242,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(String.class, Double.class), StringConversions::toDouble); DEFAULT_FACTORY.put(pair(Year.class, Double.class), YearConversions::toDouble); - // Boolean/boolean conversions supported DEFAULT_FACTORY.put(pair(Void.class, boolean.class), VoidConversions::toBoolean); DEFAULT_FACTORY.put(pair(Void.class, Boolean.class), VoidConversions::toNull); @@ -266,7 +263,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(String.class, Boolean.class), StringConversions::toBoolean); DEFAULT_FACTORY.put(pair(Year.class, Boolean.class), YearConversions::toBoolean); - // Character/chat conversions supported DEFAULT_FACTORY.put(pair(Void.class, char.class), VoidConversions::toChar); DEFAULT_FACTORY.put(pair(Void.class, Character.class), VoidConversions::toNull); @@ -317,7 +313,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(OffsetDateTime.class, BigInteger.class), OffsetDateTimeConversions::toBigInteger); DEFAULT_FACTORY.put(pair(Year.class, BigInteger.class), YearConversions::toBigInteger); - // BigDecimal conversions supported DEFAULT_FACTORY.put(pair(Void.class, BigDecimal.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Byte.class, BigDecimal.class), NumberConversions::integerTypeToBigDecimal); @@ -348,7 +343,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(OffsetDateTime.class, BigDecimal.class), OffsetDateTimeConversions::toBigDecimal); DEFAULT_FACTORY.put(pair(Year.class, BigDecimal.class), YearConversions::toBigDecimal); - // AtomicBoolean conversions supported DEFAULT_FACTORY.put(pair(Void.class, AtomicBoolean.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Byte.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean); @@ -419,7 +413,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(OffsetDateTime.class, AtomicLong.class), OffsetDateTimeConversions::toAtomicLong); DEFAULT_FACTORY.put(pair(Year.class, AtomicLong.class), YearConversions::toAtomicLong); - // Date conversions supported DEFAULT_FACTORY.put(pair(Void.class, Date.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Long.class, Date.class), NumberConversions::toDate); @@ -440,7 +433,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(String.class, Date.class), StringConversions::toDate); DEFAULT_FACTORY.put(pair(OffsetDateTime.class, Date.class), OffsetDateTimeConversions::toDate); - // java.sql.Date conversion supported DEFAULT_FACTORY.put(pair(Void.class, java.sql.Date.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Long.class, java.sql.Date.class), NumberConversions::toSqlDate); @@ -481,7 +473,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(String.class, Timestamp.class), StringConversions::toTimestamp); DEFAULT_FACTORY.put(pair(OffsetDateTime.class, Timestamp.class), OffsetDateTimeConversions::toTimestamp); - // Calendar conversions supported DEFAULT_FACTORY.put(pair(Void.class, Calendar.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Long.class, Calendar.class), NumberConversions::toCalendar); @@ -502,7 +493,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(String.class, Calendar.class), StringConversions::toCalendar); DEFAULT_FACTORY.put(pair(OffsetDateTime.class, Calendar.class), OffsetDateTimeConversions::toCalendar); - // LocalDate conversions supported DEFAULT_FACTORY.put(pair(Void.class, LocalDate.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Long.class, LocalDate.class), NumberConversions::toLocalDate); @@ -523,7 +513,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(String.class, LocalDate.class), StringConversions::toLocalDate); DEFAULT_FACTORY.put(pair(OffsetDateTime.class, LocalDate.class), OffsetDateTimeConversions::toLocalDate); - // LocalDateTime conversions supported DEFAULT_FACTORY.put(pair(Void.class, LocalDateTime.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Long.class, LocalDateTime.class), NumberConversions::toLocalDateTime); @@ -544,7 +533,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(String.class, LocalDateTime.class), StringConversions::toLocalDateTime); DEFAULT_FACTORY.put(pair(OffsetDateTime.class, LocalDateTime.class), OffsetDateTimeConversions::toLocalDateTime); - // LocalTime conversions supported DEFAULT_FACTORY.put(pair(Void.class, LocalTime.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Long.class, LocalTime.class), NumberConversions::toLocalTime); @@ -566,7 +554,6 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(String.class, LocalTime.class), StringConversions::toLocalTime); DEFAULT_FACTORY.put(pair(OffsetDateTime.class, LocalTime.class), OffsetDateTimeConversions::toLocalTime); - // ZonedDateTime conversions supported DEFAULT_FACTORY.put(pair(Void.class, ZonedDateTime.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Long.class, ZonedDateTime.class), NumberConversions::toZonedDateTime); @@ -651,8 +638,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(MonthDay.class, String.class), StringConversions::toString); DEFAULT_FACTORY.put(pair(OffsetDateTime.class, String.class), OffsetDateTimeConversions::toString); DEFAULT_FACTORY.put(pair(Year.class, String.class), YearConversions::toString); - - + // Duration conversions supported DEFAULT_FACTORY.put(pair(Void.class, Duration.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Duration.class, Duration.class), Converter::identity); @@ -679,10 +665,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Map.class, Instant.class), MapConversions::toInstant); DEFAULT_FACTORY.put(pair(OffsetDateTime.class, Instant.class), OffsetDateTimeConversions::toInstant); -// java.time.OffsetDateTime = com.cedarsoftware.util.io.DEFAULT_FACTORY.OffsetDateTimeFactory -// java.time.OffsetTime = com.cedarsoftware.util.io.DEFAULT_FACTORY.OffsetTimeFactory // java.time.Period = com.cedarsoftware.util.io.DEFAULT_FACTORY.PeriodFactory -// java.time.Year = com.cedarsoftware.util.io.DEFAULT_FACTORY.YearFactory // java.time.YearMonth = com.cedarsoftware.util.io.DEFAULT_FACTORY.YearMonthFactory // java.time.ZoneId = com.cedarsoftware.util.io.DEFAULT_FACTORY.ZoneIdFactory // java.time.ZoneOffset = com.cedarsoftware.util.io.DEFAULT_FACTORY.ZoneOffsetFactory @@ -737,7 +720,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(char[].class, char[].class), CharArrayConversions::toCharArray); DEFAULT_FACTORY.put(pair(byte[].class, char[].class), ByteArrayConversions::toCharArray); - //toCharBuffer + // toCharBuffer DEFAULT_FACTORY.put(pair(Void.class, CharBuffer.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(String.class, CharBuffer.class), StringConversions::toCharBuffer); DEFAULT_FACTORY.put(pair(StringBuilder.class, CharBuffer.class), StringConversions::toCharBuffer); @@ -760,8 +743,9 @@ private static void buildFactoryConversions() { // toYear DEFAULT_FACTORY.put(pair(Void.class, Year.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Year.class, Year.class), Converter::identity); + DEFAULT_FACTORY.put(pair(Number.class, Year.class), NumberConversions::toYear); DEFAULT_FACTORY.put(pair(String.class, Year.class), StringConversions::toYear); - + DEFAULT_FACTORY.put(pair(Map.class, Year.class), MapConversions::toYear); // Map conversions supported DEFAULT_FACTORY.put(pair(Void.class, Map.class), VoidConversions::toNull); diff --git a/src/main/java/com/cedarsoftware/util/convert/MapConversions.java b/src/main/java/com/cedarsoftware/util/convert/MapConversions.java index d3b1ce18..525e3944 100644 --- a/src/main/java/com/cedarsoftware/util/convert/MapConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/MapConversions.java @@ -9,6 +9,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.MonthDay; +import java.time.Year; import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Date; @@ -252,6 +253,10 @@ static MonthDay toMonthDay(Object from, Converter converter, ConverterOptions op } } + static Year toYear(Object from, Converter converter, ConverterOptions options) { + return fromSingleKey(from, converter, options, YEAR, Year.class); + } + static Map initMap(Object from, Converter converter, ConverterOptions options) { Map map = new CompactLinkedMap<>(); map.put(V, from); diff --git a/src/main/java/com/cedarsoftware/util/convert/NumberConversions.java b/src/main/java/com/cedarsoftware/util/convert/NumberConversions.java index 5f74ed62..0ffb2034 100644 --- a/src/main/java/com/cedarsoftware/util/convert/NumberConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/NumberConversions.java @@ -8,6 +8,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.Year; import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Date; @@ -254,4 +255,12 @@ static ZonedDateTime toZonedDateTime(Object from, ConverterOptions options) { static ZonedDateTime toZonedDateTime(Object from, Converter converter, ConverterOptions options) { return toZonedDateTime(from, options); } + + static Year toYear(Object from, Converter converter, ConverterOptions options) { + if (from instanceof Byte) { + throw new IllegalArgumentException("Cannot convert Byte to Year, not enough precision."); + } + Number number = (Number) from; + return Year.of(number.shortValue()); + } } diff --git a/src/main/java/com/cedarsoftware/util/convert/StringConversions.java b/src/main/java/com/cedarsoftware/util/convert/StringConversions.java index 50774e2b..d189d143 100644 --- a/src/main/java/com/cedarsoftware/util/convert/StringConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/StringConversions.java @@ -286,7 +286,13 @@ static MonthDay toMonthDay(Object from, Converter converter, ConverterOptions op return MonthDay.of(Integer.parseInt(mm), Integer.parseInt(dd)); } else { - throw new IllegalArgumentException(e); + try { + ZonedDateTime zdt = DateUtilities.parseDate(monthDay, options.getZoneId(), true); + return MonthDay.of(zdt.getMonthValue(), zdt.getDayOfMonth()); + } + catch (Exception ex) { + throw new IllegalArgumentException("Unable to extract Month-Day from string: " + monthDay); + } } } } @@ -457,8 +463,17 @@ static Year toYear(Object from, Converter converter, ConverterOptions options) { return null; } - return Year.of(Integer.parseInt(s)); + try { + return Year.of(Integer.parseInt(s)); + } + catch (NumberFormatException e) { + try { + ZonedDateTime zdt = DateUtilities.parseDate(s, options.getZoneId(), true); + return Year.of(zdt.getYear()); + } + catch (Exception ex) { + throw new IllegalArgumentException("Unable to extract 4-digit year from string: " + s); + } + } } - - } diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java index 4e46d61d..5c4477fc 100644 --- a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java +++ b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java @@ -72,7 +72,6 @@ */ class ConverterTest { - private static final LocalDateTime LDT_2023_TOKYO = LocalDateTime.of(2023, 6, 25, 0, 57, 29, 729000000); private static final LocalDateTime LDT_2023_PARIS = LocalDateTime.of(2023, 6, 24, 17, 57, 29, 729000000); private static final LocalDateTime LDT_2023_GMT = LocalDateTime.of(2023, 6, 24, 15, 57, 29, 729000000); @@ -88,8 +87,8 @@ class ConverterTest private Converter converter; - private static final LocalDate LD_MILLINNIUM_NY = LocalDate.of(1999, 12, 31); - private static final LocalDate LD_MILLINNIUM_TOKYO = LocalDate.of(2000, 1, 1); + private static final LocalDate LD_MILLENNIUM_NY = LocalDate.of(1999, 12, 31); + private static final LocalDate LD_MILLENNIUM_TOKYO = LocalDate.of(2000, 1, 1); private static final LocalDate LD_MILLENNIUM_CHICAGO = LocalDate.of(1999, 12, 31); @@ -240,7 +239,7 @@ void toByte_withIllegalArguments(Object value, String partialMessage) { @ParameterizedTest @NullAndEmptySource - void toByte_whenNullOrEmpty_andCovnertingToPrimitive_returnsZero(String s) + void toByte_whenNullOrEmpty_andConvertingToPrimitive_returnsZero(String s) { byte converted = this.converter.convert(s, byte.class); assertThat(converted).isZero(); @@ -857,20 +856,13 @@ void testEpochMillis() { assertThat(ny).isEqualTo(converted); assertThat(converted.toInstant().toEpochMilli()).isEqualTo(1687622249729L); } - - - + @ParameterizedTest @MethodSource("epochMillis_withLocalDateTimeInformation") void testCalendarToLocalDateTime(long epochMilli, ZoneId zoneId, LocalDateTime expected) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(epochMilli); - - System.out.println(Instant.ofEpochMilli(epochMilli).atZone(zoneId).toOffsetDateTime()); - - LocalDateTime localDateTime = this.converter.convert(calendar, LocalDateTime.class, createCustomZones(zoneId, zoneId)); - assertThat(localDateTime).isEqualTo(expected); } @@ -928,8 +920,8 @@ void testCalendar_roundTrip(long epochMilli, ZoneId zoneId, LocalDateTime expect private static Stream roundTrip_tokyoTime() { return Stream.of( - Arguments.of(946652400000L, TOKYO, LD_MILLINNIUM_TOKYO), - Arguments.of(946652400000L, NEW_YORK, LD_MILLINNIUM_NY), + Arguments.of(946652400000L, TOKYO, LD_MILLENNIUM_TOKYO), + Arguments.of(946652400000L, NEW_YORK, LD_MILLENNIUM_NY), Arguments.of(946652400000L, CHICAGO, LD_MILLENNIUM_CHICAGO) ); } @@ -959,8 +951,8 @@ void testCalendar_roundTrip_withLocalDate(long epochMilli, ZoneId zoneId, LocalD private static Stream localDateToLong() { return Stream.of( - Arguments.of(946616400000L, NEW_YORK, LD_MILLINNIUM_NY, TOKYO), - Arguments.of(946616400000L, NEW_YORK, LD_MILLINNIUM_NY, CHICAGO), + Arguments.of(946616400000L, NEW_YORK, LD_MILLENNIUM_NY, TOKYO), + Arguments.of(946616400000L, NEW_YORK, LD_MILLENNIUM_NY, CHICAGO), Arguments.of(946620000000L, CHICAGO, LD_MILLENNIUM_CHICAGO, TOKYO) ); } @@ -1108,7 +1100,7 @@ void testLocalDateToBigDecimalAndBack(long epochMilli, ZoneId zoneId, LocalDate @Test void testLocalDateToFloat() { - float intermediate = this.converter.convert(LD_MILLINNIUM_NY, float.class, createCustomZones(NEW_YORK, TOKYO)); + float intermediate = this.converter.convert(LD_MILLENNIUM_NY, float.class, createCustomZones(NEW_YORK, TOKYO)); assertThat((long)intermediate).isNotEqualTo(946616400000L); } @@ -1116,7 +1108,7 @@ void testLocalDateToFloat() { @Test void testLocalDateToLocalTime_withZoneChange_willBeZoneOffset() { - LocalTime intermediate = this.converter.convert(LD_MILLINNIUM_NY, LocalTime.class, createCustomZones(NEW_YORK, TOKYO)); + LocalTime intermediate = this.converter.convert(LD_MILLENNIUM_NY, LocalTime.class, createCustomZones(NEW_YORK, TOKYO)); assertThat(intermediate).hasHour(14) .hasMinute(0) @@ -1127,7 +1119,7 @@ void testLocalDateToLocalTime_withZoneChange_willBeZoneOffset() { @Test void testLocalDateToLocalTimeWithoutZoneChange_willBeMidnight() { - LocalTime intermediate = this.converter.convert(LD_MILLINNIUM_NY, LocalTime.class, createCustomZones(NEW_YORK, NEW_YORK)); + LocalTime intermediate = this.converter.convert(LD_MILLENNIUM_NY, LocalTime.class, createCustomZones(NEW_YORK, NEW_YORK)); assertThat(intermediate).hasHour(0) .hasMinute(0) diff --git a/src/test/java/com/cedarsoftware/util/convert/DateConversionTests.java b/src/test/java/com/cedarsoftware/util/convert/DateConversionTests.java index e8b3c678..c1292431 100644 --- a/src/test/java/com/cedarsoftware/util/convert/DateConversionTests.java +++ b/src/test/java/com/cedarsoftware/util/convert/DateConversionTests.java @@ -7,13 +7,8 @@ public class DateConversionTests { public void testDateToCalendarTimeZone() { Date date = new Date(); - - System.out.println(date); - TimeZone timeZone = TimeZone.getTimeZone("America/New_York"); Calendar cal = Calendar.getInstance(timeZone); cal.setTime(date); - - System.out.println(date); } }