diff --git a/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java b/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java
index f2610c89..1938dc27 100644
--- a/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java
@@ -33,13 +33,14 @@
* limitations under the License.
*/
final class BigDecimalConversions {
+ static final BigDecimal BILLION = BigDecimal.valueOf(1_000_000_000);
static final BigDecimal GRAND = BigDecimal.valueOf(1000);
private BigDecimalConversions() { }
static Calendar toCalendar(Object from, Converter converter) {
BigDecimal seconds = (BigDecimal) from;
- BigDecimal millis = seconds.multiply(BigDecimal.valueOf(1000));
+ BigDecimal millis = seconds.multiply(GRAND);
Calendar calendar = GregorianCalendar.getInstance(converter.getOptions().getTimeZone());
calendar.setTimeInMillis(millis.longValue());
return calendar;
@@ -59,7 +60,7 @@ static Duration toDuration(Object from, Converter converter) {
static LocalTime toLocalTime(Object from, Converter converter) {
BigDecimal seconds = (BigDecimal) from;
- BigDecimal nanos = seconds.multiply(BigDecimal.valueOf(1_000_000_000));
+ BigDecimal nanos = seconds.multiply(BILLION);
try {
return LocalTime.ofNanoOfDay(nanos.longValue());
}
@@ -108,4 +109,8 @@ static UUID toUUID(Object from, Converter converter) {
BigInteger bigInt = ((BigDecimal) from).toBigInteger();
return BigIntegerConversions.toUUID(bigInt, converter);
}
+
+ static BigDecimal secondsAndNanosToDouble(long seconds, long nanos) {
+ return BigDecimal.valueOf(seconds).add(BigDecimal.valueOf(nanos, 9));
+ }
}
diff --git a/src/main/java/com/cedarsoftware/util/convert/ByteConversions.java b/src/main/java/com/cedarsoftware/util/convert/ByteConversions.java
new file mode 100644
index 00000000..54ac50a3
--- /dev/null
+++ b/src/main/java/com/cedarsoftware/util/convert/ByteConversions.java
@@ -0,0 +1,27 @@
+package com.cedarsoftware.util.convert;
+
+/**
+ * @author John DeRegnaucourt (jdereg@gmail.com)
+ *
+ * Copyright (c) Cedar Software LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * License
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+final class ByteConversions {
+ private ByteConversions() {}
+
+ static Character toCharacter(Object from, Converter converter) {
+ Byte b = (Byte) from;
+ return (char) b.byteValue();
+ }
+}
diff --git a/src/main/java/com/cedarsoftware/util/convert/CharacterConversions.java b/src/main/java/com/cedarsoftware/util/convert/CharacterConversions.java
index c6d5abcf..db6c9310 100644
--- a/src/main/java/com/cedarsoftware/util/convert/CharacterConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/CharacterConversions.java
@@ -36,7 +36,7 @@ static boolean toBoolean(Object from, Converter converter) {
return (c == 1) || (c == 't') || (c == 'T') || (c == '1') || (c == 'y') || (c == 'Y');
}
- // downcasting -- not always a safe conversino
+ // down casting -- not always a safe conversion
static byte toByte(Object from, Converter converter) {
return (byte) (char) from;
}
diff --git a/src/main/java/com/cedarsoftware/util/convert/Converter.java b/src/main/java/com/cedarsoftware/util/convert/Converter.java
index 97c934ae..edbfb465 100644
--- a/src/main/java/com/cedarsoftware/util/convert/Converter.java
+++ b/src/main/java/com/cedarsoftware/util/convert/Converter.java
@@ -271,7 +271,7 @@ private static void buildFactoryConversions() {
// Character/char conversions supported
CONVERSION_DB.put(pair(Void.class, char.class), VoidConversions::toCharacter);
CONVERSION_DB.put(pair(Void.class, Character.class), VoidConversions::toNull);
- CONVERSION_DB.put(pair(Byte.class, Character.class), NumberConversions::toCharacter);
+ CONVERSION_DB.put(pair(Byte.class, Character.class), ByteConversions::toCharacter);
CONVERSION_DB.put(pair(Short.class, Character.class), NumberConversions::toCharacter);
CONVERSION_DB.put(pair(Integer.class, Character.class), NumberConversions::toCharacter);
CONVERSION_DB.put(pair(Long.class, Character.class), NumberConversions::toCharacter);
diff --git a/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java b/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java
index 60aab414..03eeff89 100644
--- a/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java
@@ -35,8 +35,10 @@ private DoubleConversions() { }
static Instant toInstant(Object from, Converter converter) {
double d = (Double) from;
long seconds = (long) d;
- long nanoAdjustment = (long) ((d - seconds) * 1_000_000_000L);
- return Instant.ofEpochSecond(seconds, nanoAdjustment);
+ // Calculate nanoseconds by taking the fractional part of the double and multiplying by 1_000_000_000,
+ // rounding to the nearest long to maintain precision.
+ long nanos = Math.round((d - seconds) * 1_000_000_000);
+ return Instant.ofEpochSecond(seconds, nanos);
}
static Date toDate(Object from, Converter converter) {
diff --git a/src/main/java/com/cedarsoftware/util/convert/DurationConversions.java b/src/main/java/com/cedarsoftware/util/convert/DurationConversions.java
index b316fd6a..75fbf861 100644
--- a/src/main/java/com/cedarsoftware/util/convert/DurationConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/DurationConversions.java
@@ -60,16 +60,12 @@ static BigInteger toBigInteger(Object from, Converter converter) {
static double toDouble(Object from, Converter converter) {
Duration duration = (Duration) from;
- return duration.getSeconds() + duration.getNano() / 1_000_000_000d;
+ return BigDecimalConversions.secondsAndNanosToDouble(duration.getSeconds(), duration.getNano()).doubleValue();
}
static BigDecimal toBigDecimal(Object from, Converter converter) {
Duration duration = (Duration) from;
- BigDecimal seconds = new BigDecimal(duration.getSeconds());
-
- // Convert nanoseconds to fractional seconds and add to seconds
- BigDecimal fracSec = BigDecimal.valueOf(duration.getNano(), 9);
- return seconds.add(fracSec);
+ return BigDecimalConversions.secondsAndNanosToDouble(duration.getSeconds(), duration.getNano());
}
static Timestamp toTimestamp(Object from, Converter converter) {
diff --git a/src/main/java/com/cedarsoftware/util/convert/InstantConversions.java b/src/main/java/com/cedarsoftware/util/convert/InstantConversions.java
index 8d6ee8d2..d82284fb 100644
--- a/src/main/java/com/cedarsoftware/util/convert/InstantConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/InstantConversions.java
@@ -59,9 +59,7 @@ static long toLong(Object from, Converter converter) {
*/
static double toDouble(Object from, Converter converter) {
Instant instant = (Instant) from;
- long seconds = instant.getEpochSecond();
- int nanoAdjustment = instant.getNano();
- return (double) seconds + (double) nanoAdjustment / 1_000_000_000d;
+ return BigDecimalConversions.secondsAndNanosToDouble(instant.getEpochSecond(), instant.getNano()).doubleValue();
}
static AtomicLong toAtomicLong(Object from, Converter converter) {
@@ -96,9 +94,7 @@ static BigInteger toBigInteger(Object from, Converter converter) {
static BigDecimal toBigDecimal(Object from, Converter converter) {
Instant instant = (Instant) from;
- long seconds = instant.getEpochSecond();
- int nanos = instant.getNano();
- return BigDecimal.valueOf(seconds).add(BigDecimal.valueOf(nanos, 9));
+ return BigDecimalConversions.secondsAndNanosToDouble(instant.getEpochSecond(), instant.getNano());
}
static LocalDateTime toLocalDateTime(Object from, Converter converter) {
diff --git a/src/main/java/com/cedarsoftware/util/convert/OffsetDateTimeConversions.java b/src/main/java/com/cedarsoftware/util/convert/OffsetDateTimeConversions.java
index 84ed93ff..30ff401d 100644
--- a/src/main/java/com/cedarsoftware/util/convert/OffsetDateTimeConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/OffsetDateTimeConversions.java
@@ -124,11 +124,6 @@ static Map toMap(Object from, Converter converter) {
static double toDouble(Object from, Converter converter) {
OffsetDateTime odt = (OffsetDateTime) from;
Instant instant = odt.toInstant();
-
- long epochSecond = instant.getEpochSecond();
- int nano = instant.getNano();
-
- // Convert seconds to milliseconds and add the fractional milliseconds
- return epochSecond + nano / 1_000_000_000.0d;
+ return BigDecimalConversions.secondsAndNanosToDouble(instant.getEpochSecond(), instant.getNano()).doubleValue();
}
}
diff --git a/src/main/java/com/cedarsoftware/util/convert/TimestampConversions.java b/src/main/java/com/cedarsoftware/util/convert/TimestampConversions.java
index 3e7bf74f..bbe54db9 100644
--- a/src/main/java/com/cedarsoftware/util/convert/TimestampConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/TimestampConversions.java
@@ -31,7 +31,7 @@ private TimestampConversions() {}
static double toDouble(Object from, Converter converter) {
Duration d = toDuration(from, converter);
- return d.getSeconds() + d.getNano() / 1_000_000_000d;
+ return BigDecimalConversions.secondsAndNanosToDouble(d.getSeconds(), d.getNano()).doubleValue();
}
static BigDecimal toBigDecimal(Object from, Converter converter) {
@@ -47,9 +47,8 @@ static BigInteger toBigInteger(Object from, Converter converter) {
static Duration toDuration(Object from, Converter converter) {
Timestamp timestamp = (Timestamp) from;
- Instant epoch = Instant.EPOCH;
Instant timestampInstant = timestamp.toInstant();
- return Duration.between(epoch, timestampInstant);
+ return Duration.between(Instant.EPOCH, timestampInstant);
}
static OffsetDateTime toOffsetDateTime(Object from, Converter converter) {
diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java
index 03ebf86b..1733acf2 100644
--- a/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java
+++ b/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java
@@ -77,6 +77,7 @@
class ConverterEverythingTest {
private static final String TOKYO = "Asia/Tokyo";
private static final ZoneId TOKYO_Z = ZoneId.of(TOKYO);
+ private static final ZoneOffset TOKYO_ZO = ZoneOffset.of("+09:00");
private static final TimeZone TOKYO_TZ = TimeZone.getTimeZone(TOKYO_Z);
private static final Set> immutable = new HashSet<>();
private static final long now = System.currentTimeMillis();
@@ -125,9 +126,9 @@ public ZoneId getZoneId() {
loadByteTest();
loadShortTests();
loadIntegerTests();
- loadLongTests(now);
+ loadLongTests();
loadFloatTests();
- loadDoubleTests(now);
+ loadDoubleTests();
loadBooleanTests();
loadCharacterTests();
loadBigIntegerTests();
@@ -143,7 +144,7 @@ public ZoneId getZoneId() {
loadPeriodTests();
loadYearTests();
loadZoneIdTests();
- loadTimestampTests(now);
+ loadTimestampTests();
loadLocalDateTests();
loadLocalTimeTests();
loadLocalDateTimeTests();
@@ -228,6 +229,13 @@ private static void loadAtomicIntegerTests() {
{ new AtomicLong(1), new AtomicInteger((byte)1), true},
{ new AtomicLong(Integer.MAX_VALUE), new AtomicInteger(Integer.MAX_VALUE), true},
});
+ TEST_DB.put(pair(BigInteger.class, AtomicInteger.class), new Object[][] {
+ { BigInteger.valueOf(Integer.MIN_VALUE), new AtomicInteger(Integer.MIN_VALUE), true},
+ { BigInteger.valueOf(-1), new AtomicInteger((byte)-1), true},
+ { BigInteger.valueOf(0), new AtomicInteger(0), true},
+ { BigInteger.valueOf(1), new AtomicInteger((byte)1), true},
+ { BigInteger.valueOf(Integer.MAX_VALUE), new AtomicInteger(Integer.MAX_VALUE), true},
+ });
}
/**
@@ -240,6 +248,13 @@ private static void loadAtomicLongTests() {
TEST_DB.put(pair(AtomicLong.class, AtomicLong.class), new Object[][]{
{new AtomicLong(16), new AtomicLong(16)}
});
+ TEST_DB.put(pair(BigInteger.class, AtomicLong.class), new Object[][] {
+ { BigInteger.valueOf(Long.MIN_VALUE), new AtomicLong(Long.MIN_VALUE), true},
+ { BigInteger.valueOf(-1), new AtomicLong((byte)-1), true},
+ { BigInteger.valueOf(0), new AtomicLong(0), true},
+ { BigInteger.valueOf(1), new AtomicLong((byte)1), true},
+ { BigInteger.valueOf(Long.MAX_VALUE), new AtomicLong(Long.MAX_VALUE), true},
+ });
TEST_DB.put(pair(Instant.class, AtomicLong.class), new Object[][]{
{Instant.parse("0000-01-01T00:00:00Z"), new AtomicLong(-62167219200000L), true},
{Instant.parse("0000-01-01T00:00:00.001Z"), new AtomicLong(-62167219199999L), true},
@@ -267,37 +282,6 @@ private static void loadStringTests() {
TEST_DB.put(pair(Void.class, String.class), new Object[][]{
{null, null}
});
- TEST_DB.put(pair(Byte.class, String.class), new Object[][]{
- {(byte) 0, "0"},
- {Byte.MIN_VALUE, "-128"},
- {Byte.MAX_VALUE, "127"},
- });
- TEST_DB.put(pair(Short.class, String.class), new Object[][]{
- {(short) 0, "0", true},
- {Short.MIN_VALUE, "-32768", true},
- {Short.MAX_VALUE, "32767", true},
- });
- TEST_DB.put(pair(Integer.class, String.class), new Object[][]{
- {0, "0", true},
- {Integer.MIN_VALUE, "-2147483648", true},
- {Integer.MAX_VALUE, "2147483647", true},
- });
- TEST_DB.put(pair(Long.class, String.class), new Object[][]{
- {0L, "0", true},
- {Long.MIN_VALUE, "-9223372036854775808", true},
- {Long.MAX_VALUE, "9223372036854775807", true},
- });
- TEST_DB.put(pair(Float.class, String.class), new Object[][]{
- {0f, "0", true},
- {0.0f, "0", true},
- {Float.MIN_VALUE, "1.4E-45", true},
- {-Float.MAX_VALUE, "-3.4028235E38", true},
- {Float.MAX_VALUE, "3.4028235E38", true},
- {12345679f, "1.2345679E7", true},
- {0.000000123456789f, "1.2345679E-7", true},
- {12345f, "12345.0", true},
- {0.00012345f, "1.2345E-4", true},
- });
TEST_DB.put(pair(Double.class, String.class), new Object[][]{
{0d, "0"},
{0.0, "0"},
@@ -309,25 +293,17 @@ private static void loadStringTests() {
{12345d, "12345.0"},
{0.00012345d, "1.2345E-4"},
});
- TEST_DB.put(pair(Boolean.class, String.class), new Object[][]{
- {false, "false"},
- {true, "true"}
- });
- TEST_DB.put(pair(Character.class, String.class), new Object[][]{
- {'1', "1"},
- {(char) 32, " "},
- });
TEST_DB.put(pair(BigInteger.class, String.class), new Object[][]{
{new BigInteger("-1"), "-1"},
{BigInteger.ZERO, "0"},
{new BigInteger("1"), "1"},
});
TEST_DB.put(pair(BigDecimal.class, String.class), new Object[][]{
- {new BigDecimal("-1"), "-1"},
- {new BigDecimal("-1.0"), "-1"},
+ {new BigDecimal("-1"), "-1", true},
+ {new BigDecimal("-1.0"), "-1", true},
{BigDecimal.ZERO, "0", true},
- {new BigDecimal("0.0"), "0"},
- {new BigDecimal("1.0"), "1"},
+ {new BigDecimal("0.0"), "0", true},
+ {new BigDecimal("1.0"), "1", true},
{new BigDecimal("3.141519265358979323846264338"), "3.141519265358979323846264338", true},
});
TEST_DB.put(pair(AtomicBoolean.class, String.class), new Object[][]{
@@ -434,65 +410,17 @@ private static void loadStringTests() {
TEST_DB.put(pair(String.class, String.class), new Object[][]{
{"same", "same"},
});
- TEST_DB.put(pair(Duration.class, String.class), new Object[][]{
- {Duration.parse("PT20.345S"), "PT20.345S", true},
- {Duration.ofSeconds(60), "PT1M", true},
- });
- TEST_DB.put(pair(Instant.class, String.class), new Object[][]{
- {Instant.ofEpochMilli(0), "1970-01-01T00:00:00Z", true},
- {Instant.ofEpochMilli(1), "1970-01-01T00:00:00.001Z", true},
- {Instant.ofEpochMilli(1000), "1970-01-01T00:00:01Z", true},
- {Instant.ofEpochMilli(1001), "1970-01-01T00:00:01.001Z", true},
- {Instant.ofEpochSecond(0), "1970-01-01T00:00:00Z", true},
- {Instant.ofEpochSecond(1), "1970-01-01T00:00:01Z", true},
- {Instant.ofEpochSecond(60), "1970-01-01T00:01:00Z", true},
- {Instant.ofEpochSecond(61), "1970-01-01T00:01:01Z", true},
- {Instant.ofEpochSecond(0, 0), "1970-01-01T00:00:00Z", true},
- {Instant.ofEpochSecond(0, 1), "1970-01-01T00:00:00.000000001Z", true},
- {Instant.ofEpochSecond(0, 999999999), "1970-01-01T00:00:00.999999999Z", true},
- {Instant.ofEpochSecond(0, 9999999999L), "1970-01-01T00:00:09.999999999Z", true},
- });
TEST_DB.put(pair(LocalTime.class, String.class), new Object[][]{
{LocalTime.of(9, 26), "09:26"},
{LocalTime.of(9, 26, 17), "09:26:17"},
{LocalTime.of(9, 26, 17, 1), "09:26:17.000000001"},
});
- TEST_DB.put(pair(MonthDay.class, String.class), new Object[][]{
- {MonthDay.of(1, 1), "--01-01", true},
- {MonthDay.of(12, 31), "--12-31", true},
- });
- TEST_DB.put(pair(YearMonth.class, String.class), new Object[][]{
- {YearMonth.of(2024, 1), "2024-01", true},
- {YearMonth.of(2024, 12), "2024-12", true},
- });
- TEST_DB.put(pair(Period.class, String.class), new Object[][]{
- {Period.of(6, 3, 21), "P6Y3M21D", true},
- {Period.ofWeeks(160), "P1120D", true},
- });
- TEST_DB.put(pair(ZoneId.class, String.class), new Object[][]{
- {ZoneId.of("America/New_York"), "America/New_York", true},
- {ZoneId.of("Z"), "Z", true},
- {ZoneId.of("UTC"), "UTC", true},
- {ZoneId.of("GMT"), "GMT", true},
- });
- TEST_DB.put(pair(ZoneOffset.class, String.class), new Object[][]{
- {ZoneOffset.of("+1"), "+01:00", true},
- {ZoneOffset.of("+0109"), "+01:09", true},
- });
TEST_DB.put(pair(OffsetTime.class, String.class), new Object[][]{
{OffsetTime.parse("10:15:30+01:00"), "10:15:30+01:00", true},
});
TEST_DB.put(pair(OffsetDateTime.class, String.class), new Object[][]{
{OffsetDateTime.parse("2024-02-10T10:15:07+01:00"), "2024-02-10T10:15:07+01:00", true},
});
- TEST_DB.put(pair(Year.class, String.class), new Object[][]{
- {Year.of(2024), "2024", true},
- {Year.of(1582), "1582", true},
- {Year.of(500), "500", true},
- {Year.of(1), "1", true},
- {Year.of(0), "0", true},
- {Year.of(-1), "-1", true},
- });
TEST_DB.put(pair(URL.class, String.class), new Object[][]{
{toURL("https://domain.com"), "https://domain.com", true},
{toURL("http://localhost"), "http://localhost", true},
@@ -554,9 +482,9 @@ private static void loadZoneOffsetTests() {
});
TEST_DB.put(pair(String.class, ZoneOffset.class), new Object[][]{
{"-00:00", ZoneOffset.of("+00:00")},
- {"-05:00", ZoneOffset.of("-05:00")},
+ {"-05:00", ZoneOffset.of("-05:00"), true},
{"+5", ZoneOffset.of("+05:00")},
- {"+05:00:01", ZoneOffset.of("+05:00:01")},
+ {"+05:00:01", ZoneOffset.of("+05:00:01"), true},
{"America/New_York", new IllegalArgumentException("Unknown time-zone offset: 'America/New_York'")},
});
TEST_DB.put(pair(Map.class, ZoneOffset.class), new Object[][]{
@@ -583,7 +511,7 @@ private static void loadZoneDateTimeTests() {
});
TEST_DB.put(pair(Double.class, ZonedDateTime.class), new Object[][]{
{-62167219200.0, ZonedDateTime.parse("0000-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z), true},
- {-0.000000001, ZonedDateTime.parse("1969-12-31T23:59:59.999999999Z").withZoneSameInstant(TOKYO_Z)}, // IEEE-754 limit prevents reverse test
+ {-0.000000001, ZonedDateTime.parse("1969-12-31T23:59:59.999999999Z").withZoneSameInstant(TOKYO_Z), true},
{0d, ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z), true},
{0.000000001, ZonedDateTime.parse("1970-01-01T00:00:00.000000001Z").withZoneSameInstant(TOKYO_Z), true},
{86400d, ZonedDateTime.parse("1970-01-02T00:00:00Z").withZoneSameInstant(TOKYO_Z), true},
@@ -628,18 +556,6 @@ private static void loadLocalDateTimeTests() {
{new AtomicLong(0), LocalDateTime.parse("1970-01-01T00:00:00").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
{new AtomicLong(1), LocalDateTime.parse("1970-01-01T00:00:00.001").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
});
- TEST_DB.put(pair(Double.class, LocalDateTime.class), new Object[][]{
- {-0.000000001, LocalDateTime.parse("1969-12-31T23:59:59.999999999").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime()}, // IEEE-754 prevents perfect symmetry
- {0d, LocalDateTime.parse("1970-01-01T00:00:00").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
- {0.000000001, LocalDateTime.parse("1970-01-01T00:00:00.000000001").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
- });
- TEST_DB.put(pair(BigDecimal.class, LocalDateTime.class), new Object[][]{
- {new BigDecimal("-62167219200"), LocalDateTime.parse("0000-01-01T00:00:00").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
- {new BigDecimal("-62167219199.999999999"), LocalDateTime.parse("0000-01-01T00:00:00.000000001").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
- {new BigDecimal("-0.000000001"), LocalDateTime.parse("1969-12-31T23:59:59.999999999").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
- {BigDecimal.ZERO, LocalDateTime.parse("1970-01-01T00:00:00").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
- {new BigDecimal("0.000000001"), LocalDateTime.parse("1970-01-01T00:00:00.000000001").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
- });
}
/**
@@ -716,6 +632,7 @@ private static void loadLocalDateTests() {
{LocalDate.parse("1970-01-01"), LocalDate.parse("1970-01-01"), true}
});
TEST_DB.put(pair(Double.class, LocalDate.class), new Object[][]{ // options timezone is factored in (86,400 seconds per day)
+ {-62167252739d, LocalDate.parse("0000-01-01"), true},
{-118800d, LocalDate.parse("1969-12-31"), true},
{-32400d, LocalDate.parse("1970-01-01"), true},
{0d, LocalDate.parse("1970-01-01")}, // Showing that there is a wide range of numbers that will convert to this date
@@ -730,11 +647,17 @@ private static void loadLocalDateTests() {
{new AtomicLong(54000000), LocalDate.parse("1970-01-02"), true},
});
TEST_DB.put(pair(BigInteger.class, LocalDate.class), new Object[][]{ // options timezone is factored in (86,400 seconds per day)
- // These are all in the same date range
- {BigInteger.ZERO, ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDate() },
+ {new BigInteger("-62167252739000000000"), LocalDate.parse("0000-01-01")},
+ {new BigInteger("-62167219200000000000"), LocalDate.parse("0000-01-01")},
+ {new BigInteger("-62167219200000000000"), ZonedDateTime.parse("0000-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDate()},
+ {new BigInteger("-118800000000000"), LocalDate.parse("1969-12-31"), true},
+ {new BigInteger("-32400000000000"), LocalDate.parse("1970-01-01"), true},
+ {BigInteger.ZERO, ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDate()},
{new BigInteger("53999999000000"), LocalDate.parse("1970-01-01")},
+ {new BigInteger("54000000000000"), LocalDate.parse("1970-01-02"), true},
});
TEST_DB.put(pair(BigDecimal.class, LocalDate.class), new Object[][]{ // options timezone is factored in (86,400 seconds per day)
+ {new BigDecimal("-62167252739"), LocalDate.parse("0000-01-01")},
{new BigDecimal("-62167219200"), LocalDate.parse("0000-01-01")},
{new BigDecimal("-62167219200"), ZonedDateTime.parse("0000-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDate()},
{new BigDecimal("-118800"), LocalDate.parse("1969-12-31"), true},
@@ -749,16 +672,12 @@ private static void loadLocalDateTests() {
/**
* Timestamp
*/
- private static void loadTimestampTests(long now) {
+ private static void loadTimestampTests() {
TEST_DB.put(pair(Void.class, Timestamp.class), new Object[][]{
{null, null},
});
- // No identity test - Timestamp is mutable
- TEST_DB.put(pair(Double.class, Timestamp.class), new Object[][]{
- {-0.000000001, Timestamp.from(Instant.parse("1969-12-31T23:59:59.999999999Z"))}, // IEEE-754 limit prevents reverse test
- {0d, Timestamp.from(Instant.parse("1970-01-01T00:00:00Z")), true},
- {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(Timestamp.class, Timestamp.class), new Object[][]{
+ {Timestamp.from(Instant.parse("1970-01-01T00:00:00Z")), Timestamp.from(Instant.parse("1970-01-01T00:00:00Z"))},
});
TEST_DB.put(pair(AtomicLong.class, Timestamp.class), new Object[][]{
{new AtomicLong(-62167219200000L), Timestamp.from(Instant.parse("0000-01-01T00:00:00.000Z")), true},
@@ -776,22 +695,6 @@ private static void loadTimestampTests(long now) {
{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},
- {BigInteger.valueOf(-1000000000), Timestamp.from(Instant.parse("1969-12-31T23:59:59.000000000Z")), true},
- {BigInteger.valueOf(-999999999), Timestamp.from(Instant.parse("1969-12-31T23:59:59.000000001Z")), true},
- {BigInteger.valueOf(-900000000), Timestamp.from(Instant.parse("1969-12-31T23:59:59.100000000Z")), true},
- {BigInteger.valueOf(-100000000), Timestamp.from(Instant.parse("1969-12-31T23:59:59.900000000Z")), true},
- {BigInteger.valueOf(-1), Timestamp.from(Instant.parse("1969-12-31T23:59:59.999999999Z")), true},
- {BigInteger.ZERO, Timestamp.from(Instant.parse("1970-01-01T00:00:00.000000000Z")), true},
- {BigInteger.valueOf(1), Timestamp.from(Instant.parse("1970-01-01T00:00:00.000000001Z")), true},
- {BigInteger.valueOf(100000000), Timestamp.from(Instant.parse("1970-01-01T00:00:00.100000000Z")), true},
- {BigInteger.valueOf(900000000), Timestamp.from(Instant.parse("1970-01-01T00:00:00.900000000Z")), true},
- {BigInteger.valueOf(999999999), Timestamp.from(Instant.parse("1970-01-01T00:00:00.999999999Z")), true},
- {BigInteger.valueOf(1000000000), Timestamp.from(Instant.parse("1970-01-01T00:00:01.000000000Z")), true},
- {new BigInteger("253374983881000000000"), Timestamp.from(Instant.parse("9999-02-18T19:58:01.000000000Z")), true},
- });
TEST_DB.put(pair(BigDecimal.class, Timestamp.class), new Object[][]{
{new BigDecimal("-62167219200"), Timestamp.from(Instant.parse("0000-01-01T00:00:00Z")), true},
{new BigDecimal("-62167219199.999999999"), Timestamp.from(Instant.parse("0000-01-01T00:00:00.000000001Z")), true},
@@ -845,9 +748,12 @@ private static void loadZoneIdTests() {
{TOKYO_Z, TOKYO_Z},
});
TEST_DB.put(pair(String.class, ZoneId.class), new Object[][]{
- {"America/New_York", NY_Z},
- {"Asia/Tokyo", TOKYO_Z},
+ {"America/New_York", NY_Z, true},
+ {"Asia/Tokyo", TOKYO_Z, true},
{"America/Cincinnati", new IllegalArgumentException("Unknown time-zone ID: 'America/Cincinnati'")},
+ {"Z", ZoneId.of("Z"), true},
+ {"UTC", ZoneId.of("UTC"), true},
+ {"GMT", ZoneId.of("GMT"), true},
});
TEST_DB.put(pair(Map.class, ZoneId.class), new Object[][]{
{mapOf("_v", "America/New_York"), NY_Z},
@@ -875,6 +781,11 @@ private static void loadYearTests() {
{"2000", Year.of(2000), true},
{"2024", Year.of(2024), true},
{"1670", Year.of(1670), true},
+ {"1582", Year.of(1582), true},
+ {"500", Year.of(500), true},
+ {"1", Year.of(1), true},
+ {"0", Year.of(0), true},
+ {"-1", Year.of(-1), true},
{"PONY", new IllegalArgumentException("Unable to parse 4-digit year from 'PONY'")},
});
TEST_DB.put(pair(Map.class, Year.class), new Object[][]{
@@ -909,7 +820,10 @@ private static void loadPeriodTests() {
{"P1Y1D", Period.of(1, 0, 1), true},
{"P1Y1M1D", Period.of(1, 1, 1), true},
{"P10Y10M10D", Period.of(10, 10, 10), true},
+ {"P6Y3M21D", Period.of(6, 3, 21), true},
+ {"P1120D", Period.ofWeeks(160), true},
{"PONY", new IllegalArgumentException("Unable to parse 'PONY' as a Period.")},
+
});
TEST_DB.put(pair(Map.class, Period.class), new Object[][]{
{mapOf("_v", "P0D"), Period.of(0, 0, 0)},
@@ -932,11 +846,13 @@ private static void loadYearMonthTests() {
{YearMonth.of(1999, 6), YearMonth.of(1999, 6), true},
});
TEST_DB.put(pair(String.class, YearMonth.class), new Object[][]{
- {"2024-01", YearMonth.of(2024, 1)},
+ {"2024-01", YearMonth.of(2024, 1), true},
{"2024-1", new IllegalArgumentException("Unable to extract Year-Month from string: 2024-1")},
{"2024-1-1", YearMonth.of(2024, 1)},
{"2024-06-01", YearMonth.of(2024, 6)},
+ {"2024-06", YearMonth.of(2024, 6), true},
{"2024-12-31", YearMonth.of(2024, 12)},
+ {"2024-12", YearMonth.of(2024, 12), true},
{"05:45 2024-12-31", YearMonth.of(2024, 12)},
});
TEST_DB.put(pair(Map.class, YearMonth.class), new Object[][]{
@@ -1008,25 +924,19 @@ private static void loadOffsetDateTimeTests() {
{OffsetDateTime.parse("2024-02-18T06:31:55.987654321Z"), OffsetDateTime.parse("2024-02-18T06:31:55.987654321Z"), true},
});
TEST_DB.put(pair(Double.class, OffsetDateTime.class), new Object[][]{
- {-0.000000001, OffsetDateTime.parse("1969-12-31T23:59:59.999999999Z").withOffsetSameInstant(tokyoOffset)}, // IEEE-754 resolution prevents perfect symmetry (close)
+ {-1.0, OffsetDateTime.parse("1969-12-31T23:59:59Z").withOffsetSameInstant(tokyoOffset), true},
+ {-0.000000002, OffsetDateTime.parse("1969-12-31T23:59:59.999999998Z").withOffsetSameInstant(tokyoOffset), true},
+ {-0.000000001, OffsetDateTime.parse("1969-12-31T23:59:59.999999999Z").withOffsetSameInstant(tokyoOffset), true},
{0d, OffsetDateTime.parse("1970-01-01T00:00:00Z").withOffsetSameInstant(tokyoOffset), true},
{0.000000001, OffsetDateTime.parse("1970-01-01T00:00:00.000000001Z").withOffsetSameInstant(tokyoOffset), true},
+ {0.000000002, OffsetDateTime.parse("1970-01-01T00:00:00.000000002Z").withOffsetSameInstant(tokyoOffset), true},
+ {1.0, OffsetDateTime.parse("1970-01-01T00:00:01Z").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), 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()), 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},
- });
}
/**
@@ -1039,23 +949,12 @@ private static void loadDurationTests() {
TEST_DB.put(pair(String.class, Duration.class), new Object[][]{
{"PT1S", Duration.ofSeconds(1), true},
{"PT10S", Duration.ofSeconds(10), true},
+ {"PT1M", Duration.ofSeconds(60), true},
{"PT1M40S", Duration.ofSeconds(100), true},
{"PT16M40S", Duration.ofSeconds(1000), true},
+ {"PT20.345S", Duration.parse("PT20.345S") , true},
{"PT2H46M40S", Duration.ofSeconds(10000), true},
});
- TEST_DB.put(pair(Long.class, Duration.class), new Object[][]{
- {Long.MIN_VALUE / 2, Duration.ofMillis(Long.MIN_VALUE / 2), true},
- {(long) Integer.MIN_VALUE, Duration.ofMillis(Integer.MIN_VALUE), true},
- {-1L, Duration.ofMillis(-1), true},
- {0L, Duration.ofMillis(0), true},
- {1L, Duration.ofMillis(1), true},
- {(long) Integer.MAX_VALUE, Duration.ofMillis(Integer.MAX_VALUE), true},
- {Long.MAX_VALUE / 2, Duration.ofMillis(Long.MAX_VALUE / 2), true},
- });
- TEST_DB.put(pair(Double.class, Duration.class), new Object[][]{
- {-0.000000001, Duration.ofNanos(-1)}, // IEEE 754 prevents reverse
- {3.000000006d, Duration.ofSeconds(3, 6)}, // IEEE 754 prevents reverse
- });
TEST_DB.put(pair(BigInteger.class, Duration.class), new Object[][]{
{BigInteger.valueOf(-1000000), Duration.ofNanos(-1000000), true},
{BigInteger.valueOf(-1000), Duration.ofNanos(-1000), true},
@@ -1069,16 +968,6 @@ private static void loadDurationTests() {
{BigInteger.valueOf(Long.MAX_VALUE), Duration.ofNanos(Long.MAX_VALUE), true},
{BigInteger.valueOf(Long.MIN_VALUE), Duration.ofNanos(Long.MIN_VALUE), true},
});
- TEST_DB.put(pair(BigDecimal.class, Duration.class), new Object[][]{
- {new BigDecimal("-0.000000001"), Duration.ofNanos(-1), true},
- {BigDecimal.ZERO, Duration.ofNanos(0), true},
- {new BigDecimal("0.000000001"), Duration.ofNanos(1), true},
- {new BigDecimal("100"), Duration.ofSeconds(100), true},
- {new BigDecimal("1"), Duration.ofSeconds(1), true},
- {new BigDecimal("100"), Duration.ofSeconds(100), true},
- {new BigDecimal("100"), Duration.ofSeconds(100), true},
- {new BigDecimal("3.000000006"), Duration.ofSeconds(3, 6), true},
- });
}
/**
@@ -1088,11 +977,13 @@ private static void loadSqlDateTests() {
TEST_DB.put(pair(Void.class, java.sql.Date.class), new Object[][]{
{null, null}
});
- // No identity test for Date, as it is mutable
+ TEST_DB.put(pair(java.sql.Date.class, java.sql.Date.class), new Object[][] {
+ { new java.sql.Date(0), new java.sql.Date(0) },
+ });
TEST_DB.put(pair(Double.class, java.sql.Date.class), new Object[][]{
{-62167219200.0, new java.sql.Date(Instant.parse("0000-01-01T00:00:00Z").toEpochMilli()), true},
{-62167219199.999, new java.sql.Date(Instant.parse("0000-01-01T00:00:00.001Z").toEpochMilli()), true},
- {-1.002d, new java.sql.Date(Instant.parse("1969-12-31T23:59:58.998Z").toEpochMilli()), true}, // IEEE754 resolution issue on -1.001 (-1.0009999999)
+ {-1.002d, new java.sql.Date(Instant.parse("1969-12-31T23:59:58.998Z").toEpochMilli()), true},
{-1d, new java.sql.Date(Instant.parse("1969-12-31T23:59:59Z").toEpochMilli()), true},
{-0.002, new java.sql.Date(Instant.parse("1969-12-31T23:59:59.998Z").toEpochMilli()), true},
{-0.001, new java.sql.Date(Instant.parse("1969-12-31T23:59:59.999Z").toEpochMilli()), true},
@@ -1122,6 +1013,7 @@ private static void loadSqlDateTests() {
{new BigDecimal("0.001"), new java.sql.Date(Instant.parse("1970-01-01T00:00:00.001Z").toEpochMilli()), true},
{new BigDecimal(".999"), new java.sql.Date(Instant.parse("1970-01-01T00:00:00.999Z").toEpochMilli()), true},
{new BigDecimal("1"), new java.sql.Date(Instant.parse("1970-01-01T00:00:01Z").toEpochMilli()), true},
+
});
}
@@ -1237,17 +1129,24 @@ private static void loadInstantTests() {
{Instant.parse("1996-12-24T00:00:00Z"), Instant.parse("1996-12-24T00:00:00Z")}
});
TEST_DB.put(pair(String.class, Instant.class), new Object[][]{
+ {"0000-01-01T00:00:00Z", Instant.ofEpochMilli(-62167219200000L), true},
+ {"0000-01-01T00:00:00.001Z", Instant.ofEpochMilli(-62167219199999L), true},
+ {"1969-12-31T23:59:59.999Z", Instant.ofEpochMilli(-1), true},
+ {"1970-01-01T00:00:00Z", Instant.ofEpochMilli(0), true},
+ {"1970-01-01T00:00:00.001Z", Instant.ofEpochMilli(1), true},
+ {"1970-01-01T00:00:01Z", Instant.ofEpochMilli(1000), true},
+ {"1970-01-01T00:00:01.001Z", Instant.ofEpochMilli(1001), true},
+ {"1970-01-01T00:01:00Z", Instant.ofEpochSecond(60), true},
+ {"1970-01-01T00:01:01Z", Instant.ofEpochSecond(61), true},
+ {"1970-01-01T00:00:00Z", Instant.ofEpochSecond(0, 0), true},
+ {"1970-01-01T00:00:00.000000001Z", Instant.ofEpochSecond(0, 1), true},
+ {"1970-01-01T00:00:00.999999999Z", Instant.ofEpochSecond(0, 999999999), true},
+ {"1970-01-01T00:00:09.999999999Z", Instant.ofEpochSecond(0, 9999999999L), true},
{"", null},
{" ", null},
{"1980-01-01T00:00:00Z", Instant.parse("1980-01-01T00:00:00Z"), true},
{"2024-12-31T23:59:59.999999999Z", Instant.parse("2024-12-31T23:59:59.999999999Z"), true},
});
- TEST_DB.put(pair(Double.class, Instant.class), new Object[][]{
- {-62167219200d, Instant.parse("0000-01-01T00:00:00Z"), true},
- {-0.000000001, Instant.parse("1969-12-31T23:59:59.999999999Z")}, // IEEE-754 precision not good enough for reverse
- {0d, Instant.parse("1970-01-01T00:00:00Z"), true},
- {0.000000001, Instant.parse("1970-01-01T00:00:00.000000001Z"), true},
- });
}
/**
@@ -1260,9 +1159,6 @@ private static void loadBigDecimalTests() {
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}
- });
TEST_DB.put(pair(AtomicInteger.class, BigDecimal.class), new Object[][] {
{ new AtomicInteger(Integer.MIN_VALUE), BigDecimal.valueOf(Integer.MIN_VALUE), true},
{ new AtomicInteger(-1), BigDecimal.valueOf(-1), true},
@@ -1284,55 +1180,35 @@ private static void loadBigDecimalTests() {
{Date.from(Instant.parse("1970-01-01T00:00:00Z")), BigDecimal.ZERO, true},
{Date.from(Instant.parse("1970-01-01T00:00:00.001Z")), new BigDecimal("0.001"), true},
});
- TEST_DB.put(pair(java.sql.Date.class, BigDecimal.class), new Object[][]{
- {new java.sql.Date(Instant.parse("0000-01-01T00:00:00Z").toEpochMilli()), new BigDecimal("-62167219200"), true},
- {new java.sql.Date(Instant.parse("0000-01-01T00:00:00.001Z").toEpochMilli()), new BigDecimal("-62167219199.999"), true},
- {new java.sql.Date(Instant.parse("1969-12-31T23:59:59.999Z").toEpochMilli()), new BigDecimal("-0.001"), true},
- {new java.sql.Date(Instant.parse("1970-01-01T00:00:00Z").toEpochMilli()), BigDecimal.ZERO, true},
- {new java.sql.Date(Instant.parse("1970-01-01T00:00:00.001Z").toEpochMilli()), new BigDecimal("0.001"), true},
- });
- TEST_DB.put(pair(Timestamp.class, BigDecimal.class), new Object[][]{
- {Timestamp.from(Instant.parse("0000-01-01T00:00:00Z")), new BigDecimal("-62167219200"), true},
- {Timestamp.from(Instant.parse("0000-01-01T00:00:00.000000001Z")), new BigDecimal("-62167219199.999999999"), true},
- {Timestamp.from(Instant.parse("1969-12-31T23:59:59.999999999Z")), new BigDecimal("-0.000000001"), true},
- {Timestamp.from(Instant.parse("1970-01-01T00:00:00Z")), BigDecimal.ZERO, true},
- {Timestamp.from(Instant.parse("1970-01-01T00:00:00.000000001Z")), new BigDecimal("0.000000001"), true},
- });
- TEST_DB.put(pair(LocalDate.class, BigDecimal.class), new Object[][]{
- {LocalDate.parse("0000-01-01"), new BigDecimal("-62167252739"), true}, // Proves it always works from "startOfDay", using the zoneId from options
- {LocalDate.parse("1969-12-31"), new BigDecimal("-118800"), true},
- {LocalDate.parse("1970-01-01"), new BigDecimal("-32400"), true},
- {LocalDate.parse("1970-01-02"), new BigDecimal("54000"), true},
- {ZonedDateTime.parse("1969-12-31T00:00:00Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDate(), new BigDecimal("-118800"), true}, // Proves it always works from "startOfDay", using the zoneId from options
- {ZonedDateTime.parse("1969-12-31T23:59:59.999999999Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDate(), new BigDecimal("-118800"), true}, // Proves it always works from "startOfDay", using the zoneId from options
- {ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDate(), new BigDecimal("-32400"), true}, // Proves it always works from "startOfDay", using the zoneId from options
- {ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDate(), new BigDecimal("-32400"), true},
- {ZonedDateTime.parse("1970-01-01T00:00:00.000000001Z").withZoneSameInstant(TOKYO_Z).toLocalDate(), new BigDecimal("-32400"), true},
- });
TEST_DB.put(pair(LocalDateTime.class, BigDecimal.class), new Object[][]{
{ZonedDateTime.parse("0000-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), new BigDecimal("-62167219200.0"), true},
{ZonedDateTime.parse("0000-01-01T00:00:00.000000001Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), new BigDecimal("-62167219199.999999999"), true},
- {ZonedDateTime.parse("1969-12-31T00:00:00.999999999Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), new BigDecimal("-86399.000000001"), true},
- {ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime(), new BigDecimal("-32400"), true}, // Time portion affects the answer unlike LocalDate
+ {ZonedDateTime.parse("1969-12-31T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), new BigDecimal("-86400"), true},
+ {ZonedDateTime.parse("1969-12-31T00:00:00.000000001Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), new BigDecimal("-86399.999999999"), true},
+ {ZonedDateTime.parse("1969-12-31T23:59:59.999999999Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), new BigDecimal("-0.000000001"), true},
{ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), BigDecimal.ZERO, true},
{ZonedDateTime.parse("1970-01-01T00:00:00.000000001Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), new BigDecimal("0.000000001"), true},
});
TEST_DB.put(pair(OffsetDateTime.class, BigDecimal.class), new Object[][]{ // no reverse due to .toString adding zone offset
- {OffsetDateTime.parse("0000-01-01T00:00:00Z"), new BigDecimal("-62167219200")},
- {OffsetDateTime.parse("0000-01-01T00:00:00.000000001Z"), new BigDecimal("-62167219199.999999999")},
- {OffsetDateTime.parse("1969-12-31T23:59:59.999999999Z"), new BigDecimal("-0.000000001")},
- {OffsetDateTime.parse("1970-01-01T00:00:00Z"), BigDecimal.ZERO},
- {OffsetDateTime.parse("1970-01-01T00:00:00.000000001Z"), new BigDecimal("0.000000001")},
+ {OffsetDateTime.parse("0000-01-01T00:00:00Z").withOffsetSameInstant(TOKYO_ZO), new BigDecimal("-62167219200")},
+ {OffsetDateTime.parse("0000-01-01T00:00:00.000000001Z").withOffsetSameInstant(TOKYO_ZO), new BigDecimal("-62167219199.999999999")},
+ {OffsetDateTime.parse("1969-12-31T23:59:59.999999999Z").withOffsetSameInstant(TOKYO_ZO), new BigDecimal("-0.000000001"), true},
+ {OffsetDateTime.parse("1970-01-01T00:00:00Z").withOffsetSameInstant(TOKYO_ZO), BigDecimal.ZERO, true},
+ {OffsetDateTime.parse("1970-01-01T00:00:00.000000001Z").withOffsetSameInstant(TOKYO_ZO), new BigDecimal(".000000001"), true},
+
});
TEST_DB.put(pair(Duration.class, BigDecimal.class), new Object[][]{
{Duration.ofSeconds(-1, -1), new BigDecimal("-1.000000001"), true},
{Duration.ofSeconds(-1), new BigDecimal("-1"), true},
{Duration.ofSeconds(0), BigDecimal.ZERO, true},
+ {Duration.ofNanos(0), BigDecimal.ZERO, true},
{Duration.ofSeconds(1), new BigDecimal("1"), true},
{Duration.ofNanos(1), new BigDecimal("0.000000001"), true},
{Duration.ofNanos(1_000_000_000), new BigDecimal("1"), true},
{Duration.ofNanos(2_000_000_001), new BigDecimal("2.000000001"), true},
+ {Duration.ofSeconds(3, 6), new BigDecimal("3.000000006"), true},
{Duration.ofSeconds(10, 9), new BigDecimal("10.000000009"), true},
+ {Duration.ofSeconds(100), new BigDecimal("100"), true},
{Duration.ofDays(1), new BigDecimal("86400"), true},
});
TEST_DB.put(pair(Instant.class, BigDecimal.class), new Object[][]{ // JDK 1.8 cannot handle the format +01:00 in Instant.parse(). JDK11+ handles it fine.
@@ -1370,33 +1246,13 @@ private static void loadBigIntegerTests() {
TEST_DB.put(pair(Void.class, BigInteger.class), new Object[][]{
{null, null},
});
- TEST_DB.put(pair(Byte.class, BigInteger.class), new Object[][]{
- {(byte) -1, BigInteger.valueOf(-1), true},
- {(byte) 0, BigInteger.ZERO, true},
- {Byte.MIN_VALUE, BigInteger.valueOf(Byte.MIN_VALUE), true},
- {Byte.MAX_VALUE, BigInteger.valueOf(Byte.MAX_VALUE), true},
- });
- TEST_DB.put(pair(Short.class, BigInteger.class), new Object[][]{
- {(short) -1, BigInteger.valueOf(-1), true},
- {(short) 0, BigInteger.ZERO, true},
- {Short.MIN_VALUE, BigInteger.valueOf(Short.MIN_VALUE), true},
- {Short.MAX_VALUE, BigInteger.valueOf(Short.MAX_VALUE), true},
- });
- TEST_DB.put(pair(Integer.class, BigInteger.class), new Object[][]{
- {-1, BigInteger.valueOf(-1), true},
- {0, BigInteger.ZERO, true},
- {Integer.MIN_VALUE, BigInteger.valueOf(Integer.MIN_VALUE), true},
- {Integer.MAX_VALUE, BigInteger.valueOf(Integer.MAX_VALUE), true},
- });
- TEST_DB.put(pair(Long.class, BigInteger.class), new Object[][]{
- {-1L, BigInteger.valueOf(-1), true},
- {0L, BigInteger.ZERO, true},
- {Long.MIN_VALUE, BigInteger.valueOf(Long.MIN_VALUE), true},
- {Long.MAX_VALUE, BigInteger.valueOf(Long.MAX_VALUE), true},
- });
TEST_DB.put(pair(Float.class, BigInteger.class), new Object[][]{
+ {-1.99f, BigInteger.valueOf(-1)},
{-1f, BigInteger.valueOf(-1), true},
{0f, BigInteger.ZERO, true},
+ {1f, BigInteger.valueOf(1), true},
+ {1.1f, BigInteger.valueOf(1)},
+ {1.99f, BigInteger.valueOf(1)},
{1.0e6f, new BigInteger("1000000"), true},
{-16777216f, BigInteger.valueOf(-16777216), true},
{16777216f, BigInteger.valueOf(16777216), true},
@@ -1404,19 +1260,11 @@ private static void loadBigIntegerTests() {
TEST_DB.put(pair(Double.class, BigInteger.class), new Object[][]{
{-1d, BigInteger.valueOf(-1), true},
{0d, BigInteger.ZERO, true},
+ {1d, new BigInteger("1"), true},
{1.0e9d, new BigInteger("1000000000"), true},
{-9007199254740991d, BigInteger.valueOf(-9007199254740991L), true},
{9007199254740991d, BigInteger.valueOf(9007199254740991L), true},
});
- TEST_DB.put(pair(Boolean.class, BigInteger.class), new Object[][]{
- {false, BigInteger.ZERO, true},
- {true, BigInteger.valueOf(1), true},
- });
- TEST_DB.put(pair(Character.class, BigInteger.class), new Object[][]{
- {(char) 0, BigInteger.ZERO, true},
- {(char) 1, BigInteger.valueOf(1), true},
- {(char) 65535, BigInteger.valueOf(65535), true},
- });
TEST_DB.put(pair(BigInteger.class, BigInteger.class), new Object[][]{
{new BigInteger("16"), BigInteger.valueOf(16), true},
});
@@ -1430,22 +1278,6 @@ private static void loadBigIntegerTests() {
{BigDecimal.valueOf(1.0e6d), new BigInteger("1000000")},
{BigDecimal.valueOf(-16777216), BigInteger.valueOf(-16777216), true},
});
- TEST_DB.put(pair(AtomicBoolean.class, BigInteger.class), new Object[][]{
- {new AtomicBoolean(false), BigInteger.ZERO},
- {new AtomicBoolean(true), BigInteger.valueOf(1)},
- });
- TEST_DB.put(pair(AtomicInteger.class, BigInteger.class), new Object[][]{
- {new AtomicInteger(-1), BigInteger.valueOf(-1)},
- {new AtomicInteger(0), BigInteger.ZERO},
- {new AtomicInteger(Integer.MIN_VALUE), BigInteger.valueOf(Integer.MIN_VALUE)},
- {new AtomicInteger(Integer.MAX_VALUE), BigInteger.valueOf(Integer.MAX_VALUE)},
- });
- TEST_DB.put(pair(AtomicLong.class, BigInteger.class), new Object[][]{
- {new AtomicLong(-1), BigInteger.valueOf(-1)},
- {new AtomicLong(0), BigInteger.ZERO},
- {new AtomicLong(Long.MIN_VALUE), BigInteger.valueOf(Long.MIN_VALUE)},
- {new AtomicLong(Long.MAX_VALUE), BigInteger.valueOf(Long.MAX_VALUE)},
- });
TEST_DB.put(pair(Date.class, BigInteger.class), new Object[][]{
{Date.from(Instant.parse("0000-01-01T00:00:00Z")), new BigInteger("-62167219200000000000"), true},
{Date.from(Instant.parse("0001-02-18T19:58:01Z")), new BigInteger("-62131377719000000000"), true},
@@ -1502,13 +1334,6 @@ private static void loadBigIntegerTests() {
{Instant.parse("1970-01-01T00:00:01.000000000Z"), BigInteger.valueOf(1000000000), true},
{Instant.parse("9999-02-18T19:58:01.000000000Z"), new BigInteger("253374983881000000000"), true},
});
- TEST_DB.put(pair(LocalDate.class, BigInteger.class), new Object[][]{
- {ZonedDateTime.parse("1969-12-31T00:00:00Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDate(), new BigInteger("-118800000000000"), true}, // Proves it always works from "startOfDay", using the zoneId from options
- {ZonedDateTime.parse("1969-12-31T23:59:59.999999999Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDate(), new BigInteger("-118800000000000"), true}, // Proves it always works from "startOfDay", using the zoneId from options
- {ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDate(), new BigInteger("-32400000000000"), true}, // Proves it always works from "startOfDay", using the zoneId from options
- {ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDate(), new BigInteger("-32400000000000"), true},
- {ZonedDateTime.parse("1970-01-01T00:00:00.000000001Z").withZoneSameInstant(TOKYO_Z).toLocalDate(), new BigInteger("-32400000000000"), true},
- });
TEST_DB.put(pair(LocalDateTime.class, BigInteger.class), new Object[][]{
{ZonedDateTime.parse("0000-01-01T00:00:00Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime(), new BigInteger("-62167252739000000000"), true},
{ZonedDateTime.parse("0000-01-01T00:00:00.000000001Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime(), new BigInteger("-62167252738999999999"), true},
@@ -1569,11 +1394,11 @@ private static void loadBigIntegerTests() {
{"0.0", BigInteger.ZERO},
});
TEST_DB.put(pair(OffsetDateTime.class, BigInteger.class), new Object[][]{
- {OffsetDateTime.parse("0000-01-01T00:00:00Z"), new BigInteger("-62167219200000000000")},
- {OffsetDateTime.parse("0000-01-01T00:00:00.000000001Z"), new BigInteger("-62167219199999999999")},
- {OffsetDateTime.parse("1969-12-31T23:59:59.999999999Z"), new BigInteger("-1")},
- {OffsetDateTime.parse("1970-01-01T00:00:00Z"), BigInteger.ZERO},
- {OffsetDateTime.parse("1970-01-01T00:00:00.000000001Z"), new BigInteger("1")},
+ {OffsetDateTime.parse("0000-01-01T00:00:00Z").withOffsetSameInstant(TOKYO_ZO), new BigInteger("-62167219200000000000")},
+ {OffsetDateTime.parse("0000-01-01T00:00:00.000000001Z").withOffsetSameInstant(TOKYO_ZO), new BigInteger("-62167219199999999999")},
+ {OffsetDateTime.parse("1969-12-31T23:59:59.999999999Z").withOffsetSameInstant(TOKYO_ZO), new BigInteger("-1"), true},
+ {OffsetDateTime.parse("1970-01-01T00:00:00Z").withOffsetSameInstant(TOKYO_ZO), BigInteger.ZERO, true},
+ {OffsetDateTime.parse("1970-01-01T00:00:00.000000001Z").withOffsetSameInstant(TOKYO_ZO), new BigInteger("1"), true},
});
TEST_DB.put(pair(Year.class, BigInteger.class), new Object[][]{
{Year.of(2024), BigInteger.valueOf(2024)},
@@ -1590,29 +1415,30 @@ private static void loadCharacterTests() {
TEST_DB.put(pair(Void.class, Character.class), new Object[][]{
{null, null},
});
- TEST_DB.put(pair(Byte.class, Character.class), new Object[][]{
- {(byte) -1, new IllegalArgumentException("Value '-1' out of range to be converted to character"),},
- {(byte) 0, (char) 0, true},
- {(byte) 1, (char) 1, true},
- {Byte.MAX_VALUE, (char) Byte.MAX_VALUE, true},
- });
TEST_DB.put(pair(Short.class, Character.class), new Object[][]{
{(short) -1, new IllegalArgumentException("Value '-1' out of range to be converted to character"),},
{(short) 0, (char) 0, true},
{(short) 1, (char) 1, true},
+ {(short) 49, '1', true},
+ {(short) 48, '0', true},
{Short.MAX_VALUE, (char) Short.MAX_VALUE, true},
});
TEST_DB.put(pair(Integer.class, Character.class), new Object[][]{
{-1, new IllegalArgumentException("Value '-1' out of range to be converted to character"),},
{0, (char) 0, true},
{1, (char) 1, true},
+ {49, '1', true},
+ {48, '0', true},
{65535, (char) 65535, true},
{65536, new IllegalArgumentException("Value '65536' out of range to be converted to character")},
+
});
TEST_DB.put(pair(Long.class, Character.class), new Object[][]{
{-1L, new IllegalArgumentException("Value '-1' out of range to be converted to character"),},
{0L, (char) 0L, true},
{1L, (char) 1L, true},
+ {48L, '0', true},
+ {49L, '1', true},
{65535L, (char) 65535L, true},
{65536L, new IllegalArgumentException("Value '65536' out of range to be converted to character")},
});
@@ -1620,6 +1446,8 @@ private static void loadCharacterTests() {
{-1f, new IllegalArgumentException("Value '-1' out of range to be converted to character"),},
{0f, (char) 0, true},
{1f, (char) 1, true},
+ {49f, '1', true},
+ {48f, '0', true},
{65535f, (char) 65535f, true},
{65536f, new IllegalArgumentException("Value '65536' out of range to be converted to character")},
});
@@ -1627,13 +1455,11 @@ private static void loadCharacterTests() {
{-1d, new IllegalArgumentException("Value '-1' out of range to be converted to character")},
{0d, (char) 0, true},
{1d, (char) 1, true},
+ {48d, '0', true},
+ {49d, '1', true},
{65535d, (char) 65535d, true},
{65536d, new IllegalArgumentException("Value '65536' out of range to be converted to character")},
});
- TEST_DB.put(pair(Boolean.class, Character.class), new Object[][]{
- {false, (char) 0, true},
- {true, (char) 1, true},
- });
TEST_DB.put(pair(Character.class, Character.class), new Object[][]{
{(char) 0, (char) 0, true},
{(char) 1, (char) 1, true},
@@ -1688,7 +1514,9 @@ private static void loadCharacterTests() {
{mapOf("_v", 65536), new IllegalArgumentException("Value '65536' out of range to be converted to character")},
});
TEST_DB.put(pair(String.class, Character.class), new Object[][]{
+ {" ", (char) 32, true},
{"0", '0', true},
+ {"1", '1', true},
{"A", 'A', true},
{"{", '{', true},
{"\uD83C", '\uD83C', true},
@@ -1709,22 +1537,22 @@ private static void loadBooleanTests() {
TEST_DB.put(pair(Byte.class, Boolean.class), new Object[][]{
{(byte) -2, true},
{(byte) -1, true},
- {(byte) 0, false},
- {(byte) 1, true},
+ {(byte) 0, false, true},
+ {(byte) 1, true, true},
{(byte) 2, true},
});
TEST_DB.put(pair(Short.class, Boolean.class), new Object[][]{
{(short) -2, true},
- {(short) -1, true},
- {(short) 0, false},
- {(short) 1, true},
+ {(short) -1, true },
+ {(short) 0, false, true},
+ {(short) 1, true, true},
{(short) 2, true},
});
TEST_DB.put(pair(Integer.class, Boolean.class), new Object[][]{
{-2, true},
{-1, true},
- {0, false},
- {1, true},
+ {0, false, true},
+ {1, true, true},
{2, true},
});
TEST_DB.put(pair(Long.class, Boolean.class), new Object[][]{
@@ -1757,13 +1585,13 @@ private static void loadBooleanTests() {
{false, false},
});
TEST_DB.put(pair(Character.class, Boolean.class), new Object[][]{
- {(char) 1, true},
+ {(char) 0, false, true},
+ {(char) 1, true, true},
+ {'0', false},
{'1', true},
{'2', false},
{'a', false},
{'z', false},
- {(char) 0, false},
- {'0', false},
});
TEST_DB.put(pair(AtomicBoolean.class, Boolean.class), new Object[][]{
{new AtomicBoolean(true), true, true},
@@ -1786,7 +1614,7 @@ private static void loadBooleanTests() {
TEST_DB.put(pair(BigInteger.class, Boolean.class), new Object[][]{
{BigInteger.valueOf(-2), true},
{BigInteger.valueOf(-1), true},
- {BigInteger.ZERO, false, true},
+ {BigInteger.ZERO, false, true, true},
{BigInteger.valueOf(1), true, true},
{BigInteger.valueOf(2), true},
});
@@ -1830,20 +1658,13 @@ private static void loadBooleanTests() {
/**
* Double/double
*/
- private static void loadDoubleTests(long now) {
+ private static void loadDoubleTests() {
TEST_DB.put(pair(Void.class, double.class), new Object[][]{
{null, 0d}
});
TEST_DB.put(pair(Void.class, Double.class), new Object[][]{
{null, null}
});
- TEST_DB.put(pair(Byte.class, Double.class), new Object[][]{
- {(byte) -1, -1d},
- {(byte) 0, 0d},
- {(byte) 1, 1d},
- {Byte.MIN_VALUE, (double) Byte.MIN_VALUE},
- {Byte.MAX_VALUE, (double) Byte.MAX_VALUE},
- });
TEST_DB.put(pair(Short.class, Double.class), new Object[][]{
{(short) -1, -1d},
{(short) 0, 0d},
@@ -1889,17 +1710,13 @@ private static void loadDoubleTests(long now) {
{true, 1d},
{false, 0d},
});
- TEST_DB.put(pair(Character.class, Double.class), new Object[][]{
- {'1', 49d},
- {'0', 48d},
- {(char) 1, 1d},
- {(char) 0, 0d},
- });
TEST_DB.put(pair(Duration.class, Double.class), new Object[][]{
{Duration.ofSeconds(-1, -1), -1.000000001, true},
{Duration.ofSeconds(-1), -1d, true},
{Duration.ofSeconds(0), 0d, true},
{Duration.ofSeconds(1), 1d, true},
+ {Duration.ofSeconds(3, 6), 3.000000006d, true},
+ {Duration.ofNanos(-1), -0.000000001, true},
{Duration.ofNanos(1), 0.000000001, true},
{Duration.ofNanos(1_000_000_000), 1d, true},
{Duration.ofNanos(2_000_000_001), 2.000000001, true},
@@ -1909,48 +1726,20 @@ private static void loadDoubleTests(long now) {
TEST_DB.put(pair(Instant.class, Double.class), new Object[][]{ // JDK 1.8 cannot handle the format +01:00 in Instant.parse(). JDK11+ handles it fine.
{Instant.parse("0000-01-01T00:00:00Z"), -62167219200.0, true},
{Instant.parse("1969-12-31T00:00:00Z"), -86400d, true},
- {Instant.parse("1969-12-31T00:00:00Z"), -86400d, true},
{Instant.parse("1969-12-31T00:00:00.999999999Z"), -86399.000000001, true},
-// {Instant.parse("1969-12-31T23:59:59.999999999Z"), -0.000000001 }, // IEEE-754 double cannot represent this number precisely
+ {Instant.parse("1969-12-31T23:59:59.999999999Z"), -0.000000001, true },
{Instant.parse("1970-01-01T00:00:00Z"), 0d, true},
{Instant.parse("1970-01-01T00:00:00.000000001Z"), 0.000000001, true},
{Instant.parse("1970-01-02T00:00:00Z"), 86400d, true},
{Instant.parse("1970-01-02T00:00:00.000000001Z"), 86400.000000001, true},
});
- TEST_DB.put(pair(LocalDate.class, Double.class), new Object[][]{
- {LocalDate.parse("0000-01-01"), -62167252739d, true}, // Proves it always works from "startOfDay", using the zoneId from options
- {LocalDate.parse("1969-12-31"), -118800d, true},
- {LocalDate.parse("1970-01-01"), -32400d, true},
- {LocalDate.parse("1970-01-02"), 54000d, true},
- {ZonedDateTime.parse("1969-12-31T00:00:00Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDate(), -118800d, true}, // Proves it always works from "startOfDay", using the zoneId from options
- {ZonedDateTime.parse("1969-12-31T23:59:59.999999999Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDate(), -118800d, true}, // Proves it always works from "startOfDay", using the zoneId from options
- {ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDate(), -32400d, true}, // Proves it always works from "startOfDay", using the zoneId from options
- {ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDate(), -32400d, true},
- {ZonedDateTime.parse("1970-01-01T00:00:00.000000001Z").withZoneSameInstant(TOKYO_Z).toLocalDate(), -32400d, true},
- });
TEST_DB.put(pair(LocalDateTime.class, Double.class), new Object[][]{
{ZonedDateTime.parse("0000-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), -62167219200.0, true},
- {ZonedDateTime.parse("1969-12-31T00:00:00.999999999Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), -86399.000000001, true},
- {ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime(), -32400d, true}, // Time portion affects the answer unlike LocalDate
+ {ZonedDateTime.parse("1969-12-31T23:59:59.999999998Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), -0.000000002, true},
+ {ZonedDateTime.parse("1969-12-31T23:59:59.999999999Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), -0.000000001, true},
{ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), 0d, true},
{ZonedDateTime.parse("1970-01-01T00:00:00.000000001Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), 0.000000001, true},
- });
- TEST_DB.put(pair(ZonedDateTime.class, Double.class), new Object[][]{ // no reverse due to .toString adding zone name
- {ZonedDateTime.parse("0000-01-01T00:00:00Z"), -62167219200.0},
- {ZonedDateTime.parse("1969-12-31T23:59:58.9Z"), -1.1},
- {ZonedDateTime.parse("1969-12-31T23:59:59Z"), -1d},
-// {ZonedDateTime.parse("1969-12-31T23:59:59.999999999Z"), -0.000000001}, // IEEE-754 double resolution not quite good enough to represent, but very close.
- {ZonedDateTime.parse("1970-01-01T00:00:00Z"), 0d},
- {ZonedDateTime.parse("1970-01-01T00:00:00.000000001Z"), 0.000000001},
- });
- TEST_DB.put(pair(OffsetDateTime.class, Double.class), new Object[][]{ // OffsetDateTime .toString() method prevents reverse
- {OffsetDateTime.parse("0000-01-01T00:00:00Z"), -62167219200.0},
- {OffsetDateTime.parse("1969-12-31T23:59:58.9Z"), -1.1},
- {OffsetDateTime.parse("1969-12-31T23:59:59.000000001Z"), -0.999999999},
- {OffsetDateTime.parse("1969-12-31T23:59:59Z"), -1d},
-// {OffsetDateTime.parse("1969-12-31T23:59:59.999999999Z"), -0.000000001}, // IEEE-754 double resolution not quite good enough to represent, but very close.
- {OffsetDateTime.parse("1970-01-01T00:00:00Z"), 0d},
- {OffsetDateTime.parse("1970-01-01T00:00:00.000000001Z"), 0.000000001},
+ {ZonedDateTime.parse("1970-01-01T00:00:00.000000002Z").withZoneSameInstant(TOKYO_Z).toLocalDateTime(), 0.000000002, true},
});
TEST_DB.put(pair(Date.class, Double.class), new Object[][]{
{new Date(Long.MIN_VALUE), (double) Long.MIN_VALUE / 1000d, true},
@@ -1962,23 +1751,12 @@ private static void loadDoubleTests(long now) {
{new Date(Integer.MAX_VALUE), (double) Integer.MAX_VALUE / 1000d, true},
{new Date(Long.MAX_VALUE), (double) Long.MAX_VALUE / 1000d, true},
});
- TEST_DB.put(pair(java.sql.Date.class, Double.class), new Object[][]{
- {new java.sql.Date(Long.MIN_VALUE), (double) Long.MIN_VALUE / 1000d, true},
- {new java.sql.Date(Integer.MIN_VALUE), (double) Integer.MIN_VALUE / 1000d, true},
- {new java.sql.Date(0), 0d, true},
- {new java.sql.Date(now), (double) now / 1000d, true},
- {new java.sql.Date(Instant.parse("2024-02-18T06:31:55.987654321Z").toEpochMilli()), 1708237915.987, true}, // java.sql.Date only has millisecond resolution
- {new java.sql.Date(Instant.parse("2024-02-18T06:31:55.123456789Z").toEpochMilli()), 1708237915.123, true}, // java.sql.Date only has millisecond resolution
- {new java.sql.Date(Integer.MAX_VALUE), (double) Integer.MAX_VALUE / 1000d, true},
- {new java.sql.Date(Long.MAX_VALUE), (double) Long.MAX_VALUE / 1000d, true},
- });
TEST_DB.put(pair(Timestamp.class, Double.class), new Object[][]{
- {new Timestamp(0), 0d, true},
+ {new Timestamp(0), 0.0, true},
+ {new Timestamp((long) (now * 1000d)), (double) now, true},
{Timestamp.from(Instant.parse("1969-12-31T00:00:00Z")), -86400d, true},
- {Timestamp.from(Instant.parse("1969-12-31T00:00:00.000000001Z")), -86399.999999999}, // IEEE-754 resolution issue (almost symmetrical)
- {Timestamp.from(Instant.parse("1969-12-31T00:00:01Z")), -86399d, true},
- {Timestamp.from(Instant.parse("1969-12-31T23:59:58.9Z")), -1.1, true},
- {Timestamp.from(Instant.parse("1969-12-31T23:59:59Z")), -1.0, true},
+ {Timestamp.from(Instant.parse("1969-12-31T00:00:00.000000001Z")), -86399.999999999, true},
+ {Timestamp.from(Instant.parse("1969-12-31T23:59:59.999999999Z")), -0.000000001, true},
{Timestamp.from(Instant.parse("1970-01-01T00:00:00Z")), 0d, true},
{Timestamp.from(Instant.parse("1970-01-01T00:00:00.000000001Z")), 0.000000001, true},
{Timestamp.from(Instant.parse("1970-01-01T00:00:00.9Z")), 0.9, true},
@@ -2039,13 +1817,6 @@ private static void loadDoubleTests(long now) {
{new AtomicLong(-9007199254740991L), -9007199254740991d},
{new AtomicLong(9007199254740991L), 9007199254740991d},
});
- TEST_DB.put(pair(BigInteger.class, Double.class), new Object[][]{
- {new BigInteger("-1"), -1d, true},
- {BigInteger.ZERO, 0d, true},
- {new BigInteger("1"), 1d, true},
- {new BigInteger("-9007199254740991"), -9007199254740991d, true},
- {new BigInteger("9007199254740991"), 9007199254740991d, true},
- });
TEST_DB.put(pair(BigDecimal.class, Double.class), new Object[][]{
{new BigDecimal("-1"), -1d},
{new BigDecimal("-1.1"), -1.1},
@@ -2113,13 +1884,6 @@ private static void loadFloatTests() {
TEST_DB.put(pair(Void.class, Float.class), new Object[][]{
{null, null}
});
- TEST_DB.put(pair(Byte.class, Float.class), new Object[][]{
- {(byte) -1, -1f},
- {(byte) 0, 0f},
- {(byte) 1, 1f},
- {Byte.MIN_VALUE, (float) Byte.MIN_VALUE},
- {Byte.MAX_VALUE, (float) Byte.MAX_VALUE},
- });
TEST_DB.put(pair(Short.class, Float.class), new Object[][]{
{(short) -1, -1f},
{(short) 0, 0f},
@@ -2165,12 +1929,6 @@ private static void loadFloatTests() {
{true, 1f},
{false, 0f}
});
- TEST_DB.put(pair(Character.class, Float.class), new Object[][]{
- {'1', 49f},
- {'0', 48f},
- {(char) 1, 1f},
- {(char) 0, 0f},
- });
TEST_DB.put(pair(AtomicBoolean.class, Float.class), new Object[][]{
{new AtomicBoolean(true), 1f},
{new AtomicBoolean(false), 0f}
@@ -2189,13 +1947,6 @@ private static void loadFloatTests() {
{new AtomicLong(-16777216), -16777216f},
{new AtomicLong(16777216), 16777216f},
});
- TEST_DB.put(pair(BigInteger.class, Float.class), new Object[][]{
- {new BigInteger("-1"), -1f},
- {BigInteger.ZERO, 0f},
- {new BigInteger("1"), 1f},
- {new BigInteger("-16777216"), -16777216f},
- {new BigInteger("16777216"), 16777216f},
- });
TEST_DB.put(pair(BigDecimal.class, Float.class), new Object[][]{
{new BigDecimal("-1"), -1f},
{new BigDecimal("-1.1"), -1.1f},
@@ -2231,15 +1982,22 @@ private static void loadFloatTests() {
{mapOf("_v", mapOf("_v", 16777216)), 16777216f}, // Prove use of recursive call to .convert()
});
TEST_DB.put(pair(String.class, Float.class), new Object[][]{
- {"-1", -1f},
- {"-1.1", -1.1f},
- {"-1.9", -1.9f},
- {"0", 0f},
- {"1", 1f},
- {"1.1", 1.1f},
- {"1.9", 1.9f},
+ {"-1.0", -1f, true},
+ {"-1.1", -1.1f, true},
+ {"-1.9", -1.9f, true},
+ {"0", 0f, true},
+ {"1.0", 1f, true},
+ {"1.1", 1.1f, true},
+ {"1.9", 1.9f, true},
{"-16777216", -16777216f},
{"16777216", 16777216f},
+ {"1.4E-45", Float.MIN_VALUE, true},
+ {"-3.4028235E38", -Float.MAX_VALUE, true},
+ {"3.4028235E38", Float.MAX_VALUE, true},
+ {"1.2345679E7", 12345679f, true},
+ {"1.2345679E-7", 0.000000123456789f, true},
+ {"12345.0", 12345f, true},
+ {"1.2345E-4", 0.00012345f, true},
{"", 0f},
{" ", 0f},
{"crapola", new IllegalArgumentException("Value 'crapola' not parseable as a float")},
@@ -2256,20 +2014,13 @@ private static void loadFloatTests() {
/**
* Long/long
*/
- private static void loadLongTests(long now) {
+ private static void loadLongTests() {
TEST_DB.put(pair(Void.class, long.class), new Object[][]{
{null, 0L},
});
TEST_DB.put(pair(Void.class, Long.class), new Object[][]{
{null, null},
});
- TEST_DB.put(pair(Byte.class, Long.class), new Object[][]{
- {(byte) -1, -1L},
- {(byte) 0, 0L},
- {(byte) 1, 1L},
- {Byte.MIN_VALUE, (long) Byte.MIN_VALUE},
- {Byte.MAX_VALUE, (long) Byte.MAX_VALUE},
- });
TEST_DB.put(pair(Short.class, Long.class), new Object[][]{
{(short) -1, -1L},
{(short) 0, 0L},
@@ -2317,12 +2068,6 @@ private static void loadLongTests(long now) {
{true, 1L},
{false, 0L},
});
- TEST_DB.put(pair(Character.class, Long.class), new Object[][]{
- {'1', 49L},
- {'0', 48L},
- {(char) 1, 1L},
- {(char) 0, 0L},
- });
TEST_DB.put(pair(AtomicBoolean.class, Long.class), new Object[][]{
{new AtomicBoolean(true), 1L},
{new AtomicBoolean(false), 0L},
@@ -2342,13 +2087,13 @@ private static void loadLongTests(long now) {
{new AtomicLong(9223372036854775807L), Long.MAX_VALUE},
});
TEST_DB.put(pair(BigInteger.class, Long.class), new Object[][]{
- {new BigInteger("-1"), -1L},
- {BigInteger.ZERO, 0L},
- {new BigInteger("1"), 1L},
- {new BigInteger("-9223372036854775808"), Long.MIN_VALUE},
- {new BigInteger("9223372036854775807"), Long.MAX_VALUE},
- {new BigInteger("-9223372036854775809"), Long.MAX_VALUE},
- {new BigInteger("9223372036854775808"), Long.MIN_VALUE},
+ {new BigInteger("-1"), -1L, true},
+ {BigInteger.ZERO, 0L, true},
+ {new BigInteger("1"), 1L, true},
+ {new BigInteger("-9223372036854775808"), Long.MIN_VALUE, true},
+ {new BigInteger("9223372036854775807"), Long.MAX_VALUE, true},
+ {new BigInteger("-9223372036854775809"), Long.MAX_VALUE}, // Test wrap around
+ {new BigInteger("9223372036854775808"), Long.MIN_VALUE}, // Test wrap around
});
TEST_DB.put(pair(BigDecimal.class, Long.class), new Object[][]{
{new BigDecimal("-1"), -1L},
@@ -2390,15 +2135,15 @@ private static void loadLongTests(long now) {
{mapOf("_v", mapOf("_v", -9223372036854775808L)), Long.MIN_VALUE}, // Prove use of recursive call to .convert()
});
TEST_DB.put(pair(String.class, Long.class), new Object[][]{
- {"-1", -1L},
+ {"-1", -1L, true},
{"-1.1", -1L},
{"-1.9", -1L},
- {"0", 0L},
- {"1", 1L},
+ {"0", 0L, true},
+ {"1", 1L, true},
{"1.1", 1L},
{"1.9", 1L},
- {"-2147483648", -2147483648L},
- {"2147483647", 2147483647L},
+ {"-2147483648", -2147483648L, true},
+ {"2147483647", 2147483647L, true},
{"", 0L},
{" ", 0L},
{"crapola", new IllegalArgumentException("Value 'crapola' not parseable as a long value or outside -9223372036854775808 to 9223372036854775807")},
@@ -2525,13 +2270,6 @@ private static void loadIntegerTests() {
TEST_DB.put(pair(Void.class, Integer.class), new Object[][]{
{null, null},
});
- TEST_DB.put(pair(Byte.class, Integer.class), new Object[][]{
- {(byte) -1, -1},
- {(byte) 0, 0},
- {(byte) 1, 1},
- {Byte.MIN_VALUE, (int) Byte.MIN_VALUE},
- {Byte.MAX_VALUE, (int) Byte.MAX_VALUE},
- });
TEST_DB.put(pair(Short.class, Integer.class), new Object[][]{
{(short) -1, -1},
{(short) 0, 0},
@@ -2575,16 +2313,6 @@ private static void loadIntegerTests() {
{-2147483648d, Integer.MIN_VALUE},
{2147483647d, Integer.MAX_VALUE},
});
- TEST_DB.put(pair(Boolean.class, Integer.class), new Object[][]{
- {true, 1},
- {false, 0},
- });
- TEST_DB.put(pair(Character.class, Integer.class), new Object[][]{
- {'1', 49},
- {'0', 48},
- {(char) 1, 1},
- {(char) 0, 0},
- });
TEST_DB.put(pair(AtomicBoolean.class, Integer.class), new Object[][]{
{new AtomicBoolean(true), 1},
{new AtomicBoolean(false), 0},
@@ -2604,11 +2332,11 @@ private static void loadIntegerTests() {
{new AtomicLong(2147483647), Integer.MAX_VALUE, true},
});
TEST_DB.put(pair(BigInteger.class, Integer.class), new Object[][]{
- {new BigInteger("-1"), -1},
- {BigInteger.ZERO, 0},
- {new BigInteger("1"), 1},
- {new BigInteger("-2147483648"), Integer.MIN_VALUE},
- {new BigInteger("2147483647"), Integer.MAX_VALUE},
+ {new BigInteger("-1"), -1, true},
+ {BigInteger.ZERO, 0, true},
+ {new BigInteger("1"), 1, true},
+ {new BigInteger("-2147483648"), Integer.MIN_VALUE, true},
+ {new BigInteger("2147483647"), Integer.MAX_VALUE, true},
{new BigInteger("-2147483649"), Integer.MAX_VALUE},
{new BigInteger("2147483648"), Integer.MIN_VALUE},
});
@@ -2654,15 +2382,15 @@ private static void loadIntegerTests() {
{mapOf("_v", mapOf("_v", 2147483648L)), Integer.MIN_VALUE}, // Prove use of recursive call to .convert()
});
TEST_DB.put(pair(String.class, Integer.class), new Object[][]{
- {"-1", -1},
+ {"-1", -1, true},
{"-1.1", -1},
{"-1.9", -1},
- {"0", 0},
- {"1", 1},
+ {"0", 0, true},
+ {"1", 1, true},
{"1.1", 1},
{"1.9", 1},
- {"-2147483648", -2147483648},
- {"2147483647", 2147483647},
+ {"-2147483648", -2147483648, true},
+ {"2147483647", 2147483647, true},
{"", 0},
{" ", 0},
{"crapola", new IllegalArgumentException("Value 'crapola' not parseable as an int value or outside -2147483648 to 2147483647")},
@@ -2695,13 +2423,6 @@ private static void loadShortTests() {
TEST_DB.put(pair(Void.class, Short.class), new Object[][]{
{null, null},
});
- TEST_DB.put(pair(Byte.class, Short.class), new Object[][]{
- {(byte) -1, (short) -1},
- {(byte) 0, (short) 0},
- {(byte) 1, (short) 1},
- {Byte.MIN_VALUE, (short) Byte.MIN_VALUE},
- {Byte.MAX_VALUE, (short) Byte.MAX_VALUE},
- });
TEST_DB.put(pair(Short.class, Short.class), new Object[][]{
{(short) -1, (short) -1},
{(short) 0, (short) 0},
@@ -2749,16 +2470,6 @@ private static void loadShortTests() {
{-32769d, Short.MAX_VALUE}, // verify wrap around
{32768d, Short.MIN_VALUE} // verify wrap around
});
- TEST_DB.put(pair(Boolean.class, Short.class), new Object[][]{
- {true, (short) 1},
- {false, (short) 0},
- });
- TEST_DB.put(pair(Character.class, Short.class), new Object[][]{
- {'1', (short) 49},
- {'0', (short) 48},
- {(char) 1, (short) 1},
- {(char) 0, (short) 0},
- });
TEST_DB.put(pair(AtomicBoolean.class, Short.class), new Object[][]{
{new AtomicBoolean(true), (short) 1},
{new AtomicBoolean(false), (short) 0},
@@ -2782,11 +2493,11 @@ private static void loadShortTests() {
{new AtomicLong(32768), Short.MIN_VALUE},
});
TEST_DB.put(pair(BigInteger.class, Short.class), new Object[][]{
- {new BigInteger("-1"), (short) -1},
- {BigInteger.ZERO, (short) 0},
- {new BigInteger("1"), (short) 1},
- {new BigInteger("-32768"), Short.MIN_VALUE},
- {new BigInteger("32767"), Short.MAX_VALUE},
+ {new BigInteger("-1"), (short) -1, true},
+ {BigInteger.ZERO, (short) 0, true},
+ {new BigInteger("1"), (short) 1, true},
+ {new BigInteger("-32768"), Short.MIN_VALUE, true},
+ {new BigInteger("32767"), Short.MAX_VALUE, true},
{new BigInteger("-32769"), Short.MAX_VALUE},
{new BigInteger("32768"), Short.MIN_VALUE},
});
@@ -2832,15 +2543,15 @@ private static void loadShortTests() {
{mapOf("_v", mapOf("_v", 32768L)), Short.MIN_VALUE}, // Prove use of recursive call to .convert()
});
TEST_DB.put(pair(String.class, Short.class), new Object[][]{
- {"-1", (short) -1},
+ {"-1", (short) -1, true},
{"-1.1", (short) -1},
{"-1.9", (short) -1},
- {"0", (short) 0},
- {"1", (short) 1},
+ {"0", (short) 0, true},
+ {"1", (short) 1, true},
{"1.1", (short) 1},
{"1.9", (short) 1},
- {"-32768", (short) -32768},
- {"32767", (short) 32767},
+ {"-32768", (short) -32768, true},
+ {"32767", (short) 32767, true},
{"", (short) 0},
{" ", (short) 0},
{"crapola", new IllegalArgumentException("Value 'crapola' not parseable as a short value or outside -32768 to 32767")},
@@ -2925,7 +2636,7 @@ private static void loadByteTest() {
{-1.99, (byte) -1},
{-1.1, (byte) -1},
{0d, (byte) 0, true},
- {1d, (byte) 1},
+ {1d, (byte) 1, true},
{1.1, (byte) 1},
{1.999, (byte) 1},
{-128d, Byte.MIN_VALUE, true},
@@ -2933,15 +2644,13 @@ private static void loadByteTest() {
{-129d, Byte.MAX_VALUE}, // verify wrap around
{128d, Byte.MIN_VALUE} // verify wrap around
});
- TEST_DB.put(pair(Boolean.class, Byte.class), new Object[][]{
- {true, (byte) 1, true},
- {false, (byte) 0, true},
- });
TEST_DB.put(pair(Character.class, Byte.class), new Object[][]{
{'1', (byte) 49, true},
{'0', (byte) 48, true},
{(char) 1, (byte) 1, true},
{(char) 0, (byte) 0, true},
+ {(char) -1, (byte) 65535, true},
+ {(char) Byte.MAX_VALUE, Byte.MAX_VALUE, true},
});
TEST_DB.put(pair(AtomicBoolean.class, Byte.class), new Object[][]{
{new AtomicBoolean(true), (byte) 1, true},
@@ -3084,12 +2793,12 @@ private static Stream generateTestEverythingParams() {
String sourceName = Converter.getShortName(sourceClass);
String targetName = Converter.getShortName(targetClass);
Object[][] testData = entry.getValue();
-
+ int index = 0;
for (Object[] testPair : testData) {
Object source = possiblyConvertSupplier(testPair[0]);
Object target = possiblyConvertSupplier(testPair[1]);
- list.add(Arguments.of(sourceName, targetName, source, target, sourceClass, targetClass));
+ list.add(Arguments.of(sourceName, targetName, source, target, sourceClass, targetClass, index++));
}
}
@@ -3110,7 +2819,7 @@ private static Stream generateTestEverythingParamsInReverse() {
String sourceName = Converter.getShortName(sourceClass);
String targetName = Converter.getShortName(targetClass);
Object[][] testData = entry.getValue();
-
+ int index = 0;
for (Object[] testPair : testData) {
boolean reverse = false;
Object source = possiblyConvertSupplier(testPair[0]);
@@ -3124,7 +2833,7 @@ private static Stream generateTestEverythingParamsInReverse() {
continue;
}
- list.add(Arguments.of(targetName, sourceName, target, source, targetClass, sourceClass));
+ list.add(Arguments.of(targetName, sourceName, target, source, targetClass, sourceClass, index++));
}
}
@@ -3133,7 +2842,15 @@ private static Stream generateTestEverythingParamsInReverse() {
@ParameterizedTest(name = "{0}[{2}] ==> {1}[{3}]")
@MethodSource("generateTestEverythingParams")
- void testConvert(String shortNameSource, String shortNameTarget, Object source, Object target, Class> sourceClass, Class> targetClass) {
+ void testConvert(String shortNameSource, String shortNameTarget, Object source, Object target, Class> sourceClass, Class> targetClass, int index) {
+ if (index == 0) {
+ Map.Entry, Class>> entry = pair(sourceClass, targetClass);
+ Boolean alreadyCompleted = STAT_DB.get(entry);
+ if (Boolean.TRUE.equals(alreadyCompleted) && !sourceClass.equals(targetClass)) {
+ System.err.println("Duplicate test pair: " + shortNameSource + " ==> " + shortNameTarget);
+ }
+ }
+
if (source == null) {
assertEquals(sourceClass, Void.class, "On the source-side of test input, null can only appear in the Void.class data");
} else {
@@ -3232,7 +2949,7 @@ static void printStats() {
@ParameterizedTest(name = "{0}[{2}] ==> {1}[{3}]")
@MethodSource("generateTestEverythingParamsInReverse")
- void testConvertReverse(String shortNameSource, String shortNameTarget, Object source, Object target, Class> sourceClass, Class> targetClass) {
- testConvert(shortNameSource, shortNameTarget, source, target, sourceClass, targetClass);
+ void testConvertReverse(String shortNameSource, String shortNameTarget, Object source, Object target, Class> sourceClass, Class> targetClass, int index) {
+ testConvert(shortNameSource, shortNameTarget, source, target, sourceClass, targetClass, index);
}
}