diff --git a/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java b/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java index c54375c0..f2610c89 100644 --- a/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java @@ -10,7 +10,9 @@ import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.ZonedDateTime; +import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; import java.util.UUID; /** @@ -35,6 +37,14 @@ final class BigDecimalConversions { private BigDecimalConversions() { } + static Calendar toCalendar(Object from, Converter converter) { + BigDecimal seconds = (BigDecimal) from; + BigDecimal millis = seconds.multiply(BigDecimal.valueOf(1000)); + Calendar calendar = GregorianCalendar.getInstance(converter.getOptions().getTimeZone()); + calendar.setTimeInMillis(millis.longValue()); + return calendar; + } + static Instant toInstant(Object from, Converter converter) { BigDecimal seconds = (BigDecimal) from; BigDecimal nanos = seconds.remainder(BigDecimal.ONE); diff --git a/src/main/java/com/cedarsoftware/util/convert/BigIntegerConversions.java b/src/main/java/com/cedarsoftware/util/convert/BigIntegerConversions.java index fec623fb..9712bbdc 100644 --- a/src/main/java/com/cedarsoftware/util/convert/BigIntegerConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/BigIntegerConversions.java @@ -10,7 +10,9 @@ import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.ZonedDateTime; +import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; import java.util.UUID; /** @@ -32,6 +34,7 @@ */ final class BigIntegerConversions { static final BigInteger BILLION = BigInteger.valueOf(1_000_000_000); + static final BigInteger MILLION = BigInteger.valueOf(1_000_000); private BigIntegerConversions() { } @@ -78,6 +81,14 @@ static Timestamp toTimestamp(Object from, Converter converter) { return Timestamp.from(toInstant(from, converter)); } + static Calendar toCalendar(Object from, Converter converter) { + BigInteger epochNanos = (BigInteger) from; + BigInteger epochMillis = epochNanos.divide(MILLION); + Calendar calendar = GregorianCalendar.getInstance(converter.getOptions().getTimeZone()); + calendar.setTimeInMillis(epochMillis.longValue()); + return calendar; + } + static ZonedDateTime toZonedDateTime(Object from, Converter converter) { return toInstant(from, converter).atZone(converter.getOptions().getZoneId()); } diff --git a/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java b/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java index 437433f5..cbdd7a16 100644 --- a/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java @@ -44,7 +44,9 @@ static Long toLong(Object from, Converter converter) { } static double toDouble(Object from, Converter converter) { - return (double)toLong(from, converter); + Calendar calendar = (Calendar) from; + long epochMillis = calendar.getTime().getTime(); + return epochMillis / 1000.0; } static Date toDate(Object from, Converter converter) { @@ -81,11 +83,13 @@ static LocalTime toLocalTime(Object from, Converter converter) { } static BigDecimal toBigDecimal(Object from, Converter converter) { - return BigDecimal.valueOf(((Calendar) from).getTime().getTime()); + Calendar cal = (Calendar) from; + long epochMillis = cal.getTime().getTime(); + return new BigDecimal(epochMillis).divide(BigDecimalConversions.GRAND); } static BigInteger toBigInteger(Object from, Converter converter) { - return BigInteger.valueOf(((Calendar) from).getTime().getTime()); + return BigInteger.valueOf(((Calendar) from).getTime().getTime() * 1_000_000L); } static Calendar clone(Object from, Converter converter) { diff --git a/src/main/java/com/cedarsoftware/util/convert/Converter.java b/src/main/java/com/cedarsoftware/util/convert/Converter.java index 7e5911c2..97c934ae 100644 --- a/src/main/java/com/cedarsoftware/util/convert/Converter.java +++ b/src/main/java/com/cedarsoftware/util/convert/Converter.java @@ -504,9 +504,9 @@ private static void buildFactoryConversions() { CONVERSION_DB.put(pair(Short.class, Calendar.class), UNSUPPORTED); CONVERSION_DB.put(pair(Integer.class, Calendar.class), UNSUPPORTED); CONVERSION_DB.put(pair(Long.class, Calendar.class), NumberConversions::toCalendar); - CONVERSION_DB.put(pair(Double.class, Calendar.class), NumberConversions::toCalendar); - CONVERSION_DB.put(pair(BigInteger.class, Calendar.class), NumberConversions::toCalendar); - CONVERSION_DB.put(pair(BigDecimal.class, Calendar.class), NumberConversions::toCalendar); + CONVERSION_DB.put(pair(Double.class, Calendar.class), DoubleConversions::toCalendar); + CONVERSION_DB.put(pair(BigInteger.class, Calendar.class), BigIntegerConversions::toCalendar); + CONVERSION_DB.put(pair(BigDecimal.class, Calendar.class), BigDecimalConversions::toCalendar); CONVERSION_DB.put(pair(AtomicInteger.class, Calendar.class), UNSUPPORTED); CONVERSION_DB.put(pair(AtomicLong.class, Calendar.class), NumberConversions::toCalendar); CONVERSION_DB.put(pair(Date.class, Calendar.class), DateConversions::toCalendar); diff --git a/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java b/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java index baf20507..60aab414 100644 --- a/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java @@ -8,7 +8,9 @@ import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.ZonedDateTime; +import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; /** * @author John DeRegnaucourt (jdereg@gmail.com) @@ -47,6 +49,15 @@ static Date toSqlDate(Object from, Converter converter) { return new java.sql.Date((long)(d * 1000)); } + static Calendar toCalendar(Object from, Converter converter) { + double seconds = (double) from; + long epochMillis = (long)(seconds * 1000); + Calendar calendar = GregorianCalendar.getInstance(converter.getOptions().getTimeZone()); + calendar.clear(); + calendar.setTimeInMillis(epochMillis); + return calendar; + } + static LocalTime toLocalTime(Object from, Converter converter) { double seconds = (double) from; double nanos = seconds * 1_000_000_000.0; diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java index 6214f7c5..03ebf86b 100644 --- a/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java +++ b/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java @@ -50,6 +50,7 @@ import org.junit.jupiter.params.provider.MethodSource; import static com.cedarsoftware.util.MapUtilities.mapOf; +import static com.cedarsoftware.util.convert.Converter.VALUE; import static com.cedarsoftware.util.convert.Converter.pair; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -78,6 +79,7 @@ class ConverterEverythingTest { private static final ZoneId TOKYO_Z = ZoneId.of(TOKYO); private static final TimeZone TOKYO_TZ = TimeZone.getTimeZone(TOKYO_Z); private static final Set> immutable = new HashSet<>(); + private static final long now = System.currentTimeMillis(); private Converter converter; private final ConverterOptions options = new ConverterOptions() { public ZoneId getZoneId() { @@ -88,9 +90,6 @@ public ZoneId getZoneId() { private static final Map, Class>, Boolean> STAT_DB = new ConcurrentHashMap<>(500, .8f); static { - // Useful values for input - long now = System.currentTimeMillis(); - // List classes that should be checked for immutability immutable.add(byte.class); immutable.add(Byte.class); @@ -164,6 +163,9 @@ private static void loadMapTests() { TEST_DB.put(pair(Void.class, Map.class), new Object[][]{ {null, null} }); + TEST_DB.put(pair(BigDecimal.class, Map.class), new Object[][]{ + {BigDecimal.valueOf(1), mapOf(VALUE, BigDecimal.valueOf(1))} + }); } /** @@ -187,6 +189,11 @@ private static void loadAtomicBooleanTests() { { new AtomicLong((byte)0), new AtomicBoolean(false), true}, { new AtomicLong((byte)1), new AtomicBoolean(true), true}, }); + TEST_DB.put(pair(BigInteger.class, AtomicBoolean.class), new Object[][] { + { BigInteger.valueOf(-1), new AtomicBoolean(true)}, + { BigInteger.ZERO, new AtomicBoolean(false), true}, + { BigInteger.valueOf(1), new AtomicBoolean(true), true}, + }); TEST_DB.put(pair(BigDecimal.class, AtomicBoolean.class), new Object[][] { { new BigDecimal("-1.1"), new AtomicBoolean(true)}, { BigDecimal.valueOf(-1), new AtomicBoolean(true)}, @@ -582,6 +589,13 @@ private static void loadZoneDateTimeTests() { {86400d, ZonedDateTime.parse("1970-01-02T00:00:00Z").withZoneSameInstant(TOKYO_Z), true}, {86400.000000001, ZonedDateTime.parse("1970-01-02T00:00:00.000000001Z").withZoneSameInstant(TOKYO_Z), true}, }); + TEST_DB.put(pair(AtomicLong.class, ZonedDateTime.class), new Object[][]{ + {new AtomicLong(-62167219200000L), ZonedDateTime.parse("0000-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z), true}, + {new AtomicLong(-62167219199999L), ZonedDateTime.parse("0000-01-01T00:00:00.001Z").withZoneSameInstant(TOKYO_Z), true}, + {new AtomicLong(-1), ZonedDateTime.parse("1969-12-31T23:59:59.999Z").withZoneSameInstant(TOKYO_Z), true}, + {new AtomicLong(0), ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z), true}, + {new AtomicLong(1), ZonedDateTime.parse("1970-01-01T00:00:00.001Z").withZoneSameInstant(TOKYO_Z), true}, + }); TEST_DB.put(pair(BigInteger.class, ZonedDateTime.class), new Object[][]{ {new BigInteger("-62167219200000000000"), ZonedDateTime.parse("0000-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z), true}, {new BigInteger("-62167219199999999999"), ZonedDateTime.parse("0000-01-01T00:00:00.000000001Z").withZoneSameInstant(TOKYO_Z), true}, @@ -746,6 +760,22 @@ private static void loadTimestampTests(long now) { {0.000000001, Timestamp.from(Instant.parse("1970-01-01T00:00:00.000000001Z")), true}, {(double) now, new Timestamp((long) (now * 1000d)), true}, }); + TEST_DB.put(pair(AtomicLong.class, Timestamp.class), new Object[][]{ + {new AtomicLong(-62167219200000L), Timestamp.from(Instant.parse("0000-01-01T00:00:00.000Z")), true}, + {new AtomicLong(-62131377719000L), Timestamp.from(Instant.parse("0001-02-18T19:58:01.000Z")), true}, + {new AtomicLong(-1000), Timestamp.from(Instant.parse("1969-12-31T23:59:59.000000000Z")), true}, + {new AtomicLong(-999), Timestamp.from(Instant.parse("1969-12-31T23:59:59.001Z")), true}, + {new AtomicLong(-900), Timestamp.from(Instant.parse("1969-12-31T23:59:59.100000000Z")), true}, + {new AtomicLong(-100), Timestamp.from(Instant.parse("1969-12-31T23:59:59.900000000Z")), true}, + {new AtomicLong(-1), Timestamp.from(Instant.parse("1969-12-31T23:59:59.999Z")), true}, + {new AtomicLong(0), Timestamp.from(Instant.parse("1970-01-01T00:00:00.000000000Z")), true}, + {new AtomicLong(1), Timestamp.from(Instant.parse("1970-01-01T00:00:00.001Z")), true}, + {new AtomicLong(100), Timestamp.from(Instant.parse("1970-01-01T00:00:00.100Z")), true}, + {new AtomicLong(900), Timestamp.from(Instant.parse("1970-01-01T00:00:00.900Z")), true}, + {new AtomicLong(999), Timestamp.from(Instant.parse("1970-01-01T00:00:00.999Z")), true}, + {new AtomicLong(1000), Timestamp.from(Instant.parse("1970-01-01T00:00:01.000Z")), true}, + {new AtomicLong(253374983881000L), Timestamp.from(Instant.parse("9999-02-18T19:58:01.000Z")), true}, + }); TEST_DB.put(pair(BigInteger.class, Timestamp.class), new Object[][]{ {new BigInteger("-62167219200000000000"), Timestamp.from(Instant.parse("0000-01-01T00:00:00.000000000Z")), true}, {new BigInteger("-62131377719000000000"), Timestamp.from(Instant.parse("0001-02-18T19:58:01.000000000Z")), true}, @@ -982,13 +1012,18 @@ private static void loadOffsetDateTimeTests() { {0d, OffsetDateTime.parse("1970-01-01T00:00:00Z").withOffsetSameInstant(tokyoOffset), true}, {0.000000001, OffsetDateTime.parse("1970-01-01T00:00:00.000000001Z").withOffsetSameInstant(tokyoOffset), true}, }); + TEST_DB.put(pair(AtomicLong.class, OffsetDateTime.class), new Object[][]{ + {new AtomicLong(-1), OffsetDateTime.parse("1969-12-31T23:59:59.999Z").withOffsetSameInstant(tokyoOffset), true}, + {new AtomicLong(0), OffsetDateTime.parse("1970-01-01T00:00:00Z").withOffsetSameInstant(tokyoOffset), true}, + {new AtomicLong(1), OffsetDateTime.parse("1970-01-01T00:00:00.001Z").withOffsetSameInstant(tokyoOffset), true}, + }); TEST_DB.put(pair(BigInteger.class, OffsetDateTime.class), new Object[][]{ - {new BigInteger("-1"), OffsetDateTime.parse("1969-12-31T23:59:59.999999999Z").withOffsetSameInstant(tokyoOffset)}, - {BigInteger.ZERO, OffsetDateTime.parse("1970-01-01T00:00:00Z").withOffsetSameInstant(tokyoOffset)}, - {new BigInteger("1"), OffsetDateTime.parse("1970-01-01T00:00:00.000000001Z").withOffsetSameInstant(tokyoOffset)}, + {new BigInteger("-1"), OffsetDateTime.parse("1969-12-31T23:59:59.999999999Z").withOffsetSameInstant(tokyoOffset), true}, + {BigInteger.ZERO, OffsetDateTime.parse("1970-01-01T00:00:00Z").withOffsetSameInstant(tokyoOffset), true}, + {new BigInteger("1"), OffsetDateTime.parse("1970-01-01T00:00:00.000000001Z").withOffsetSameInstant(tokyoOffset), true}, }); TEST_DB.put(pair(BigDecimal.class, OffsetDateTime.class), new Object[][]{ - {new BigDecimal("-0.000000001"), OffsetDateTime.parse("1969-12-31T23:59:59.999999999Z").withOffsetSameInstant(ZonedDateTime.now(TOKYO_Z).getOffset())}, // IEEE-754 resolution prevents perfect symmetry (close) + {new BigDecimal("-0.000000001"), OffsetDateTime.parse("1969-12-31T23:59:59.999999999Z").withOffsetSameInstant(ZonedDateTime.now(TOKYO_Z).getOffset()), true}, {BigDecimal.ZERO, OffsetDateTime.parse("1970-01-01T00:00:00Z").withOffsetSameInstant(ZonedDateTime.now(TOKYO_Z).getOffset()), true}, {new BigDecimal(".000000001"), OffsetDateTime.parse("1970-01-01T00:00:00.000000001Z").withOffsetSameInstant(ZonedDateTime.now(TOKYO_Z).getOffset()), true}, }); @@ -1066,6 +1101,17 @@ private static void loadSqlDateTests() { {0.999, new java.sql.Date(Instant.parse("1970-01-01T00:00:00.999Z").toEpochMilli()), true}, {1d, new java.sql.Date(Instant.parse("1970-01-01T00:00:01Z").toEpochMilli()), true}, }); + TEST_DB.put(pair(AtomicLong.class, java.sql.Date.class), new Object[][]{ + {new AtomicLong(-62167219200000L), new java.sql.Date(Instant.parse("0000-01-01T00:00:00Z").toEpochMilli()), true}, + {new AtomicLong(-62167219199999L), new java.sql.Date(Instant.parse("0000-01-01T00:00:00.001Z").toEpochMilli()), true}, + {new AtomicLong(-1001), new java.sql.Date(Instant.parse("1969-12-31T23:59:58.999Z").toEpochMilli()), true}, + {new AtomicLong(-1000), new java.sql.Date(Instant.parse("1969-12-31T23:59:59Z").toEpochMilli()), true}, + {new AtomicLong(-1), new java.sql.Date(Instant.parse("1969-12-31T23:59:59.999Z").toEpochMilli()), true}, + {new AtomicLong(0), new java.sql.Date(Instant.parse("1970-01-01T00:00:00Z").toEpochMilli()), true}, + {new AtomicLong(1), new java.sql.Date(Instant.parse("1970-01-01T00:00:00.001Z").toEpochMilli()), true}, + {new AtomicLong(999), new java.sql.Date(Instant.parse("1970-01-01T00:00:00.999Z").toEpochMilli()), true}, + {new AtomicLong(1000), new java.sql.Date(Instant.parse("1970-01-01T00:00:01Z").toEpochMilli()), true}, + }); TEST_DB.put(pair(BigDecimal.class, java.sql.Date.class), new Object[][]{ {new BigDecimal("-62167219200"), new java.sql.Date(Instant.parse("0000-01-01T00:00:00Z").toEpochMilli()), true}, {new BigDecimal("-62167219199.999"), new java.sql.Date(Instant.parse("0000-01-01T00:00:00.001Z").toEpochMilli()), true}, @@ -1103,14 +1149,80 @@ private static void loadCalendarTests() { TEST_DB.put(pair(Void.class, Calendar.class), new Object[][]{ {null, null} }); + TEST_DB.put(pair(Calendar.class, Calendar.class), new Object[][] { + {(Supplier) () -> { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(now); + return cal; + }, (Supplier) () -> { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(now); + return cal; + } } + }); TEST_DB.put(pair(AtomicLong.class, Calendar.class), new Object[][]{ + {new AtomicLong(-1), (Supplier) () -> { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(-1); + return cal; + }, true}, {new AtomicLong(0), (Supplier) () -> { Calendar cal = Calendar.getInstance(); cal.clear(); cal.setTimeZone(TOKYO_TZ); cal.setTimeInMillis(0); return cal; - }, true} + }, true}, + {new AtomicLong(1), (Supplier) () -> { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(1); + return cal; + }, true}, + }); + TEST_DB.put(pair(BigDecimal.class, Calendar.class), new Object[][]{ + {new BigDecimal(-1), (Supplier) () -> { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(-1000); + return cal; + }, true}, + {new BigDecimal("-0.001"), (Supplier) () -> { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(-1); + return cal; + }, true}, + {BigDecimal.ZERO, (Supplier) () -> { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(0); + return cal; + }, true}, + {new BigDecimal("0.001"), (Supplier) () -> { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(1); + return cal; + }, true}, + {new BigDecimal(1), (Supplier) () -> { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(1000); + return cal; + }, true}, }); } @@ -1145,6 +1257,9 @@ private static void loadBigDecimalTests() { TEST_DB.put(pair(Void.class, BigDecimal.class), new Object[][]{ {null, null} }); + TEST_DB.put(pair(BigDecimal.class, BigDecimal.class), new Object[][]{ + {new BigDecimal("3.1415926535897932384626433"), new BigDecimal("3.1415926535897932384626433"), true} + }); TEST_DB.put(pair(String.class, BigDecimal.class), new Object[][]{ {"3.1415926535897932384626433", new BigDecimal("3.1415926535897932384626433"), true} }); @@ -1231,6 +1346,21 @@ private static void loadBigDecimalTests() { {Instant.parse("1970-01-02T00:00:00Z"), new BigDecimal("86400"), true}, {Instant.parse("1970-01-02T00:00:00.000000001Z"), new BigDecimal("86400.000000001"), true}, }); + TEST_DB.put(pair(UUID.class, BigDecimal.class), new Object[][]{ + {new UUID(0L, 0L), BigDecimal.ZERO, true}, + {new UUID(1L, 1L), new BigDecimal("18446744073709551617"), true}, + {new UUID(Long.MAX_VALUE, Long.MAX_VALUE), new BigDecimal("170141183460469231722463931679029329919"), true}, + {UUID.fromString("00000000-0000-0000-0000-000000000000"), BigDecimal.ZERO, true}, + {UUID.fromString("00000000-0000-0000-0000-000000000001"), BigDecimal.valueOf(1), true}, + {UUID.fromString("00000000-0000-0001-0000-000000000001"), new BigDecimal("18446744073709551617"), true}, + {UUID.fromString("ffffffff-ffff-ffff-ffff-ffffffffffff"), new BigDecimal("340282366920938463463374607431768211455"), true}, + {UUID.fromString("ffffffff-ffff-ffff-ffff-fffffffffffe"), new BigDecimal("340282366920938463463374607431768211454"), true}, + {UUID.fromString("f0000000-0000-0000-0000-000000000000"), new BigDecimal("319014718988379809496913694467282698240"), true}, + {UUID.fromString("f0000000-0000-0000-0000-000000000001"), new BigDecimal("319014718988379809496913694467282698241"), true}, + {UUID.fromString("7fffffff-ffff-ffff-ffff-fffffffffffe"), new BigDecimal("170141183460469231731687303715884105726"), true}, + {UUID.fromString("7fffffff-ffff-ffff-ffff-ffffffffffff"), new BigDecimal("170141183460469231731687303715884105727"), true}, + {UUID.fromString("80000000-0000-0000-0000-000000000000"), new BigDecimal("170141183460469231731687303715884105728"), true}, + }); } /** @@ -1410,9 +1540,23 @@ private static void loadBigIntegerTests() { Calendar cal = Calendar.getInstance(); cal.clear(); cal.setTimeZone(TOKYO_TZ); - cal.set(2024, Calendar.FEBRUARY, 12, 11, 38, 0); + cal.setTimeInMillis(-1); return cal; - }, BigInteger.valueOf(1707705480000L)} + }, BigInteger.valueOf(-1000000), true}, + {(Supplier) () -> { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(0); + return cal; + }, BigInteger.ZERO, true}, + {(Supplier) () -> { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(1); + return cal; + }, BigInteger.valueOf(1000000), true}, }); TEST_DB.put(pair(Number.class, BigInteger.class), new Object[][]{ {0, BigInteger.ZERO}, @@ -1844,38 +1988,38 @@ private static void loadDoubleTests(long now) { {(Supplier) () -> { Calendar cal = Calendar.getInstance(); cal.clear(); - cal.setTimeZone(TimeZone.getTimeZone("UTC")); - cal.setTimeInMillis(-1); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(-1000); return cal; - }, -1d}, + }, -1.0, true}, {(Supplier) () -> { Calendar cal = Calendar.getInstance(); cal.clear(); - cal.setTimeZone(TimeZone.getTimeZone("UTC")); - cal.setTimeInMillis(0); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(-1); return cal; - }, 0d}, + }, -0.001, true}, {(Supplier) () -> { Calendar cal = Calendar.getInstance(); cal.clear(); - cal.setTimeZone(TimeZone.getTimeZone("UTC")); - cal.setTimeInMillis(1); + cal.setTimeZone(TOKYO_TZ); + cal.setTimeInMillis(0); return cal; - }, 1d}, + }, 0d, true}, {(Supplier) () -> { Calendar cal = Calendar.getInstance(); cal.clear(); cal.setTimeZone(TOKYO_TZ); - cal.set(2024, Calendar.FEBRUARY, 12, 11, 38, 0); + cal.setTimeInMillis(1); return cal; - }, 1707705480000d}, + }, 0.001d, true}, {(Supplier) () -> { Calendar cal = Calendar.getInstance(); cal.clear(); cal.setTimeZone(TOKYO_TZ); - cal.setTimeInMillis(now); // Calendar maintains time to millisecond resolution + cal.setTimeInMillis(1000); return cal; - }, (double) now} + }, 1.0, true}, }); TEST_DB.put(pair(AtomicBoolean.class, Double.class), new Object[][]{ {new AtomicBoolean(true), 1d}, diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java index 1e3d05e3..30760fd6 100644 --- a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java +++ b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java @@ -1385,7 +1385,7 @@ void testCalendarToDouble(long epochMilli, ZoneId zoneId, LocalDate expected) { Converter converter = new Converter(createCustomZones(zoneId)); double d = converter.convert(calendar, double.class); - assertThat(d).isEqualTo((double)epochMilli); + assertThat(d * 1000).isEqualTo((double)epochMilli); } @ParameterizedTest @@ -1441,6 +1441,7 @@ void testCalendarToBigDecimal(long epochMilli, ZoneId zoneId, LocalDateTime expe Converter converter = new Converter(createCustomZones(zoneId)); BigDecimal actual = converter.convert(calendar, BigDecimal.class); + actual = actual.multiply(BigDecimal.valueOf(1000)); assertThat(actual.longValue()).isEqualTo(epochMilli); } @@ -1453,6 +1454,7 @@ void testCalendarToBigInteger(long epochMilli, ZoneId zoneId, LocalDateTime expe Converter converter = new Converter(createCustomZones(zoneId)); BigInteger actual = converter.convert(calendar, BigInteger.class); + actual = actual.divide(BigInteger.valueOf(1_000_000)); assertThat(actual.longValue()).isEqualTo(epochMilli); } @@ -1848,7 +1850,7 @@ void testBigDecimal_withObjectsThatShouldBeSameAs(Object value, BigDecimal expec @Test void testBigDecimal_witCalendar() { Calendar today = Calendar.getInstance(); - BigDecimal bd = new BigDecimal(today.getTime().getTime()); + BigDecimal bd = new BigDecimal(today.getTime().getTime()).divide(BigDecimal.valueOf(1000)); assertEquals(bd, this.converter.convert(today, BigDecimal.class)); } @@ -1909,7 +1911,7 @@ void testBigInteger_withObjectsShouldBeSameAs(Object value, BigInteger expected) @Test void testBigInteger_withCalendar() { Calendar today = Calendar.getInstance(); - BigInteger bd = BigInteger.valueOf(today.getTime().getTime()); + BigInteger bd = BigInteger.valueOf(today.getTime().getTime()).multiply(BigInteger.valueOf(1_000_000)); assertEquals(bd, this.converter.convert(today, BigInteger.class)); } @@ -2310,8 +2312,8 @@ private static Stream toCalendarParams() { Arguments.of(new Timestamp(1687622249729L)), Arguments.of(Instant.ofEpochMilli(1687622249729L)), Arguments.of(1687622249729L), - Arguments.of(BigInteger.valueOf(1687622249729L)), - Arguments.of(BigDecimal.valueOf(1687622249729L)), + Arguments.of(new BigInteger("1687622249729000000")), + Arguments.of(BigDecimal.valueOf(1687622249.729)), Arguments.of("1687622249729"), Arguments.of(new AtomicLong(1687622249729L)) ); @@ -2323,6 +2325,7 @@ void toCalendar(Object source) { Long epochMilli = 1687622249729L; + System.out.println("source.getClass().getName() = " + source.getClass().getName()); Calendar calendar = this.converter.convert(source, Calendar.class); assertEquals(calendar.getTime().getTime(), epochMilli); @@ -2359,10 +2362,11 @@ void toCalendar(Object source) // Calendar to BigInteger BigInteger bigInt = this.converter.convert(calendar, BigInteger.class); - assertEquals(now.getTime().getTime(), bigInt.longValue()); + assertEquals(now.getTime().getTime() * 1_000_000, bigInt.longValue()); // Calendar to BigDecimal BigDecimal bigDec = this.converter.convert(calendar, BigDecimal.class); + bigDec = bigDec.multiply(BigDecimal.valueOf(1000)); assertEquals(now.getTime().getTime(), bigDec.longValue()); }