This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 19e8496c91ba15cd399bff3bc66ff7d006ce0454
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat Oct 11 13:10:10 2025 +0200

    Move to `TestUtilities` methods closer to where they are used.
    Replace more usages of `java.util.Date` by `java.time.Instant`.
---
 .../apache/sis/metadata/AbstractMetadataTest.java  |   4 +-
 .../org/apache/sis/metadata/TreeTableViewTest.java | 121 +++++++++++++---
 .../extent/DefaultGeographicBoundingBoxTest.java   |   7 +-
 .../DefaultDataIdentificationTest.java             |   8 +-
 .../apache/sis/temporal/LenientDateFormatTest.java |  28 ++--
 .../parameter/UnmodifiableParameterValueTest.java  |   5 +-
 .../org/apache/sis/referencing/CommonCRSTest.java  |   2 +-
 .../sis/storage/xml/stream/StaxStreamReader.java   |   4 +-
 .../org/apache/sis/storage/gpx/MetadataTest.java   |   5 +-
 .../org/apache/sis/storage/gpx/ReaderTest.java     |  17 ++-
 .../test/org/apache/sis/storage/csv/StoreTest.java |   3 +-
 .../org/apache/sis/converter/InstantConverter.java |   1 +
 .../main/org/apache/sis/measure/RangeFormat.java   |   1 +
 .../org/apache/sis/measure/AngleFormatTest.java    |  68 +++++----
 .../test/org/apache/sis/measure/DateRangeTest.java |  58 ++++----
 .../test/org/apache/sis/test/TestUtilities.java    | 159 +--------------------
 .../apache/sis/test/self/TestUtilitiesTest.java    |  59 --------
 .../org/apache/sis/util/collection/CacheTest.java  |  19 ++-
 18 files changed, 240 insertions(+), 329 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/AbstractMetadataTest.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/AbstractMetadataTest.java
index a0d198d8ad..5ae93d10ac 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/AbstractMetadataTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/AbstractMetadataTest.java
@@ -20,7 +20,6 @@ package org.apache.sis.metadata;
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import org.apache.sis.test.TestCase;
-import static org.apache.sis.test.TestUtilities.toTreeStructure;
 
 
 /**
@@ -28,6 +27,7 @@ import static 
org.apache.sis.test.TestUtilities.toTreeStructure;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
+@SuppressWarnings("exports")
 public final class AbstractMetadataTest extends TestCase {
     /**
      * Creates a new test case.
@@ -89,6 +89,6 @@ public final class AbstractMetadataTest extends TestCase {
             "              ├─",             // Description
             "              └─",             // Instrument
             "                    (",        // Omitted cycle
-            ""}, toTreeStructure(text));
+            ""}, TreeTableViewTest.toTreeStructure(text));
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TreeTableViewTest.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TreeTableViewTest.java
index 6fd4062020..0fb5d71398 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TreeTableViewTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TreeTableViewTest.java
@@ -25,8 +25,10 @@ import java.io.ByteArrayOutputStream;
 import org.opengis.annotation.Obligation;
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.citation.Citation;
+import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.TableColumn;
+import org.apache.sis.util.collection.TreeTableFormat;
 import org.apache.sis.metadata.iso.citation.DefaultCitation;
 import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 import org.apache.sis.xml.NilReason;
@@ -34,10 +36,8 @@ import org.apache.sis.xml.NilReason;
 // Test dependencies
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
-import org.apache.sis.test.TestCase;
 import static org.apache.sis.test.Assertions.assertMultilinesEquals;
-import static org.apache.sis.test.TestUtilities.toTreeStructure;
-import static org.apache.sis.test.TestUtilities.formatMetadata;
+import org.apache.sis.test.TestCase;
 
 
 /**
@@ -46,6 +46,7 @@ import static 
org.apache.sis.test.TestUtilities.formatMetadata;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
+@SuppressWarnings("exports")
 public final class TreeTableViewTest extends TestCase {
     /**
      * Creates a new test case.
@@ -91,8 +92,70 @@ public final class TreeTableViewTest extends TestCase {
     public void testToString() {
         final TreeTableView metadata = create(ValueExistencePolicy.COMPACT);
         assertFalse(metadata.getColumns().contains(MetadataColumn.NIL_REASON));
-        assertMultilinesEquals(EXPECTED, formatMetadata(metadata));            
                 // Locale-independent
-        assertArrayEquals(toTreeStructure(EXPECTED), 
toTreeStructure(metadata.toString()));     // Locale-dependent.
+        assertMetadataTreeEquals(EXPECTED, metadata);     // Locale-independent
+        final String[] structure = {
+            "",
+            "  ├─",
+            "  ├─",
+            "  ├─",
+            "  ├─",
+            "  │   ├─",
+            "  │   └─",
+            "  ├─",
+            "  │   ├─",
+            "  │   └─",
+            "  │       └─",
+            "  │           └─",
+            "  │               └─",
+            "  ├─",
+            "  ├─",
+            "  └─",
+            ""
+            };
+        assertArrayEquals(structure, toTreeStructure(EXPECTED));    // Test of 
`toTreeStructure(CharSequence)`.
+        assertArrayEquals(structure, toTreeStructure(metadata.toString()));    
 // Locale-dependent.
+    }
+
+    /**
+     * Returns the tree structure of the given string representation, without 
the localized text.
+     * For example, given the following string:
+     *
+     * <pre class="text">
+     *   Citation
+     *     ├─Title…………………………………………………… Some title
+     *     └─Cited responsible party
+     *         └─Individual name……………… Some person of contact</pre>
+     *
+     * this method returns an array containing the following elements:
+     *
+     * <pre class="text">
+     *   "",
+     *   "  ├─",
+     *   "  └─",
+     *   "      └─"</pre>
+     *
+     * This method is used for comparing two trees having string 
representation in different locales.
+     * In such case, we cannot compare the actual text content. The best we 
can do is to compare
+     * the tree structure.
+     *
+     * @param  tree  the string representation of a tree.
+     * @return the structure of the given tree, without text.
+     */
+    static CharSequence[] toTreeStructure(final CharSequence tree) {
+        final CharSequence[] lines = CharSequences.split(tree, '\n');
+        for (int i=0; i<lines.length; i++) {
+            final CharSequence line = lines[i];
+            final int length = line.length();
+            for (int j=0; j<length;) {
+                final int c = Character.codePointAt(line, j);
+                if (Character.isLetterOrDigit(c)) {
+                    lines[i] = line.subSequence(0, j);
+                    break;
+                }
+                j += Character.charCount(c);
+            }
+        }
+        return lines;
     }
 
     /**
@@ -112,7 +175,7 @@ public final class TreeTableViewTest extends TestCase {
     public void testNilReasons() {
         final TreeTableView metadata = create(ValueExistencePolicy.NON_NULL);
         assertTrue(metadata.getColumns().contains(MetadataColumn.NIL_REASON));
-        final var citation = (DefaultCitation) 
metadata.getRoot().getUserObject();
+        final DefaultCitation citation = 
assertInstanceOf(DefaultCitation.class, metadata.getRoot().getUserObject());
         
citation.setTitle(NilReason.TEMPLATE.createNilObject(InternationalString.class));
         verify(metadata.getRoot(), null, NilReason.TEMPLATE);
     }
@@ -195,17 +258,16 @@ public final class TreeTableViewTest extends TestCase {
     @Test
     public void testSerialization() throws Exception {
         final Object original = create(ValueExistencePolicy.COMPACT);
-        final Object deserialized;
-        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        try (ObjectOutputStream out = new ObjectOutputStream(buffer)) {
+        final var buffer = new ByteArrayOutputStream();
+        try (var out = new ObjectOutputStream(buffer)) {
             out.writeObject(original);
         }
         // Now reads the object we just serialized.
-        final byte[] data = buffer.toByteArray();
-        try (ObjectInputStream in = new ObjectInputStream(new 
ByteArrayInputStream(data))) {
-            deserialized = in.readObject();
+        final TreeTableView deserialized;
+        try (var in = new ObjectInputStream(new 
ByteArrayInputStream(buffer.toByteArray()))) {
+            deserialized = assertInstanceOf(TreeTableView.class, 
in.readObject());
         }
-        assertMultilinesEquals(EXPECTED, formatMetadata((TreeTableView) 
deserialized));
+        assertMetadataTreeEquals(EXPECTED, deserialized);
     }
 
     /**
@@ -216,14 +278,39 @@ public final class TreeTableViewTest extends TestCase {
      */
     @Test
     public void testRemarks() {
-        final DefaultGeographicBoundingBox bbox = new 
DefaultGeographicBoundingBox(170, -160, -30, 40);
-        final String text = formatMetadata(bbox.asTreeTable());
-        assertMultilinesEquals(
+        final var bbox = new DefaultGeographicBoundingBox(170, -160, -30, 40);
+        assertMetadataTreeEquals(
                 "Geographic bounding box\n" +
                 "  ├─West bound longitude…… 170°E\n" +
                 "  ├─East bound longitude…… 160°W…… Bounding box crosses the 
antimeridian.\n" +   // See method javadoc.
                 "  ├─South bound latitude…… 30°S\n" +
                 "  ├─North bound latitude…… 40°N\n" +
-                "  └─Extent type code……………… True\n", text);
+                "  └─Extent type code……………… True\n", bbox.asTreeTable());
+    }
+
+    /**
+     * Asserts that the unlocalized string representation of {@code NAME},
+     * {@code VALUE} and {@code REMARKS} columns of the given tree table is 
equal to the expected string.
+     * The columns used by this methods are the columns included in default 
string representation of metadata.
+     * Dates and times, if any, will be formatted using the {@code "yyyy-MM-dd 
HH:mm:ss"} pattern in UTC timezone.
+     * This method is used mostly as a convenient way to verify the content of 
an ISO 19115 metadata object.
+     *
+     * @param  expected  the expected unlocalized string representation of the 
given tree table.
+     * @param  actual    the table for which to verify the string 
representation.
+     */
+    public static void assertMetadataTreeEquals(final String expected, final 
TreeTable actual) {
+        final String tree;
+        synchronized (UNLOCALIZED_FORMAT) {
+            tree = UNLOCALIZED_FORMAT.format(actual);
+        }
+        assertMultilinesEquals(expected, tree);
+    }
+
+    /**
+     * The format to use for unlocalized string representations.
+     */
+    private static final TreeTableFormat UNLOCALIZED_FORMAT = new 
TreeTableFormat(null, null);
+    static {
+        UNLOCALIZED_FORMAT.setColumns(TableColumn.NAME, TableColumn.VALUE, 
TableColumn.REMARKS);
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java
index 2d02c44f55..4f41827ff1 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java
@@ -25,10 +25,9 @@ import org.apache.sis.measure.Longitude;
 // Test dependencies
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
+import static 
org.apache.sis.metadata.TreeTableViewTest.assertMetadataTreeEquals;
 import static org.apache.sis.test.Assertions.assertMessageContains;
-import static org.apache.sis.test.Assertions.assertMultilinesEquals;
 import static org.apache.sis.test.Assertions.assertSingleton;
-import org.apache.sis.test.TestUtilities;
 import org.apache.sis.test.TestCase;
 
 
@@ -438,7 +437,7 @@ public final class DefaultGeographicBoundingBoxTest extends 
TestCase {
         };
         final var extent = new DefaultExtent(null, bbox, null, null);
         assertSame(bbox, assertSingleton(extent.getGeographicElements()));
-        assertMultilinesEquals(
+        assertMetadataTreeEquals(
                 "Extent\n" +
                 "  └─Geographic element\n" +
                 "      ├─West bound longitude…… 40°W\n" +
@@ -446,6 +445,6 @@ public final class DefaultGeographicBoundingBoxTest extends 
TestCase {
                 "      ├─South bound latitude…… 20°S\n" +
                 "      ├─North bound latitude…… 45°N\n" +
                 "      └─Extent type code……………… True\n",
-                TestUtilities.formatMetadata(extent.asTreeTable()));
+                extent.asTreeTable());
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java
index bf8c9e8ce6..071ab12b28 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java
@@ -36,9 +36,8 @@ import org.apache.sis.metadata.iso.extent.Extents;
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import org.apache.sis.test.TestCase;
-import org.apache.sis.test.TestUtilities;
-import static org.apache.sis.test.Assertions.assertMultilinesEquals;
 import static org.apache.sis.test.Assertions.assertTitleEquals;
+import static 
org.apache.sis.metadata.TreeTableViewTest.assertMetadataTreeEquals;
 
 
 /**
@@ -46,6 +45,7 @@ import static 
org.apache.sis.test.Assertions.assertTitleEquals;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
+@SuppressWarnings("exports")
 public final class DefaultDataIdentificationTest extends TestCase {
     /**
      * Creates a new test case.
@@ -126,7 +126,7 @@ public final class DefaultDataIdentificationTest extends 
TestCase {
      */
     @Test
     public void testToString() {
-        assertMultilinesEquals(
+        assertMetadataTreeEquals(
                 "Data identification\n" +
                 "  ├─Citation………………………………………………………… Sea Surface Temperature 
Analysis Model\n" +
                 "  │   ├─Date………………………………………………………… 2005 Sep 22\n" +
@@ -151,7 +151,7 @@ public final class DefaultDataIdentificationTest extends 
TestCase {
                 "  │   └─Character set………………………………… US-ASCII\n" +
                 "  └─Locale (2 of 2)……………………………………… fr\n" +
                 "      └─Character set………………………………… ISO-8859-1\n",
-            TestUtilities.formatMetadata(create().asTreeTable()));
+            create().asTreeTable());
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/temporal/LenientDateFormatTest.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/temporal/LenientDateFormatTest.java
index 3328d05e86..629f38248e 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/temporal/LenientDateFormatTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/temporal/LenientDateFormatTest.java
@@ -28,7 +28,6 @@ import java.text.ParseException;
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import org.apache.sis.test.TestCase;
-import static org.apache.sis.test.TestUtilities.date;
 
 
 /**
@@ -71,21 +70,28 @@ public final class LenientDateFormatTest extends TestCase {
     @Test
     public void testParse() throws ParseException {
         final long day = 1466985600000L;
-        final LenientDateFormat f = new LenientDateFormat();
+        final var f = new LenientDateFormat();
         assertEquals(day + ((16*60 + 48)*60     )*1000,      
f.parse("2016-06-27T16:48Z")      .getTime());
         assertEquals(day + ((16*60 + 48)*60 + 12)*1000,      
f.parse("2016-06-27T16:48:12Z")   .getTime());
         assertEquals(day,                                    
f.parse("2016-06-27")             .getTime());
         assertEquals(day + (( 3*60 +  2)*60 +  1)*1000 + 90, 
f.parse("2016-06-27T03:02:01.09Z").getTime());
 
-        assertEquals(date("2009-01-01 05:00:00"), 
f.parse("2009-01-01T06:00:00+01:00"));
-        assertEquals(date("2005-09-22 04:30:15"), 
f.parse("2005-09-22T04:30:15Z"));
-        assertEquals(date("2005-09-22 04:30:15"), 
f.parse("2005-09-22T04:30:15"));
-        assertEquals(date("2005-09-22 04:30:00"), f.parse("2005-09-22T04:30"));
-        assertEquals(date("2005-09-22 04:30:00"), f.parse("2005-09-22 04:30"));
-        assertEquals(date("2005-09-22 04:00:00"), f.parse("2005-09-22T04"));
-        assertEquals(date("2005-09-22 00:00:00"), f.parse("2005-09-22"));
-        assertEquals(date("2005-09-22 00:00:00"), f.parse("2005-9-22"));
-        assertEquals(date("1992-01-01 00:00:00"), f.parse("1992-1-1"));
+        assertDateEquals("2009-01-01T05:00:00Z", f, 
"2009-01-01T06:00:00+01:00");
+        assertDateEquals("2005-09-22T04:30:15Z", f, "2005-09-22T04:30:15Z");
+        assertDateEquals("2005-09-22T04:30:15Z", f, "2005-09-22T04:30:15");
+        assertDateEquals("2005-09-22T04:30:00Z", f, "2005-09-22T04:30");
+        assertDateEquals("2005-09-22T04:30:00Z", f, "2005-09-22 04:30");
+        assertDateEquals("2005-09-22T04:00:00Z", f, "2005-09-22T04");
+        assertDateEquals("2005-09-22T00:00:00Z", f, "2005-09-22");
+        assertDateEquals("2005-09-22T00:00:00Z", f, "2005-9-22");
+        assertDateEquals("1992-01-01T00:00:00Z", f, "1992-1-1");
+    }
+
+    /**
+     * Asserts that parsing the given date produces the expected result.
+     */
+    private static void assertDateEquals(final String expected, final 
LenientDateFormat f, final String date) throws ParseException {
+        assertEquals(Instant.parse(expected), f.parse(date).toInstant());
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/parameter/UnmodifiableParameterValueTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/parameter/UnmodifiableParameterValueTest.java
index 36a6a50ae0..7d28ea4044 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/parameter/UnmodifiableParameterValueTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/parameter/UnmodifiableParameterValueTest.java
@@ -17,6 +17,7 @@
 package org.apache.sis.parameter;
 
 import java.util.Date;
+import java.time.Instant;
 import org.opengis.parameter.ParameterValue;
 import org.apache.sis.util.ComparisonMode;
 
@@ -25,7 +26,6 @@ import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.apache.sis.test.Assertions.assertMessageContains;
 import org.apache.sis.test.TestCase;
-import static org.apache.sis.test.TestUtilities.date;
 
 
 /**
@@ -33,6 +33,7 @@ import static org.apache.sis.test.TestUtilities.date;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
+@SuppressWarnings("exports")
 public final class UnmodifiableParameterValueTest extends TestCase {
     /**
      * Creates a new test case.
@@ -91,7 +92,7 @@ public final class UnmodifiableParameterValueTest extends 
TestCase {
     public void testGetValue() {
         final ParameterValue<Date> modifiable = DefaultParameterDescriptorTest
                 .createSimpleOptional("Time reference", 
Date.class).createValue();
-        modifiable.setValue(date("1994-01-01 00:00:00"));
+        modifiable.setValue(Date.from(Instant.parse("1994-01-01T00:00:00Z")));
         /*
          * Create and validate an unmodifiable parameter,
          * then verify that the values are not the same.
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
index 7e14b8921f..f8f7bccfb3 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
@@ -263,7 +263,7 @@ public final class CommonCRSTest extends TestCase {
          * We need to use `java.text.DateFormat` rather than 
`Instant.parse(String)` because
          * they have different policy regarding the calendar for dates before 
October 15, 1582.
          * The `java.time` classes use the proleptic Gregorian calendar while 
`java.text` uses
-         * the prolectic Julian calendar. The latter is what we need for this 
test.
+         * the proleptic Julian calendar. The latter is what we need for this 
test.
          */
         final var dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", 
Locale.CANADA);
         dateFormat.setTimeZone(TimeZone.getTimeZone(UTC));
diff --git 
a/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/xml/stream/StaxStreamReader.java
 
b/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/xml/stream/StaxStreamReader.java
index 095b39cb8a..d000601ef7 100644
--- 
a/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/xml/stream/StaxStreamReader.java
+++ 
b/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/xml/stream/StaxStreamReader.java
@@ -41,6 +41,7 @@ import jakarta.xml.bind.JAXBException;
 import org.apache.sis.xml.bind.Context;
 import org.apache.sis.util.internal.shared.Strings;
 import org.apache.sis.io.stream.IOUtilities;
+import org.apache.sis.temporal.TemporalDate;
 import org.apache.sis.temporal.LenientDateFormat;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreContentException;
@@ -370,8 +371,7 @@ public abstract class StaxStreamReader extends StaxStreamIO 
implements XMLStream
      * @throws DateTimeParseException if the text cannot be parsed as a date.
      */
     protected final Date getElementAsDate() throws XMLStreamException {
-        final String text = getElementText();
-        return (text == null) ? null : 
Date.from(LenientDateFormat.parseInstantUTC(text));
+        return 
TemporalDate.toDate(LenientDateFormat.parseInstantUTC(getElementText()));
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.storage.xml/test/org/apache/sis/storage/gpx/MetadataTest.java
 
b/endorsed/src/org.apache.sis.storage.xml/test/org/apache/sis/storage/gpx/MetadataTest.java
index 6ea920a8da..bc10977143 100644
--- 
a/endorsed/src/org.apache.sis.storage.xml/test/org/apache/sis/storage/gpx/MetadataTest.java
+++ 
b/endorsed/src/org.apache.sis.storage.xml/test/org/apache/sis/storage/gpx/MetadataTest.java
@@ -17,6 +17,8 @@
 package org.apache.sis.storage.gpx;
 
 import java.util.List;
+import java.util.Date;
+import java.time.Instant;
 import java.net.URI;
 import java.net.URISyntaxException;
 
@@ -24,7 +26,6 @@ import java.net.URISyntaxException;
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import org.apache.sis.test.TestCase;
-import static org.apache.sis.test.TestUtilities.date;
 
 
 /**
@@ -97,7 +98,7 @@ public final class MetadataTest extends TestCase {
         metadata.copyright   = copyright;
         metadata.keywords    = List.of("sample", "metadata");
         metadata.bounds      = bounds;
-        metadata.time        = date("2010-03-01 00:00:00");
+        metadata.time        = 
Date.from(Instant.parse("2010-03-01T00:00:00Z"));
         metadata.links       = List.of(new Link(new 
URI("http://first-address.org";)),
                                        new Link(new 
URI("http://second-address.org";)),
                                        new Link(new 
URI("http://third-address.org";)));
diff --git 
a/endorsed/src/org.apache.sis.storage.xml/test/org/apache/sis/storage/gpx/ReaderTest.java
 
b/endorsed/src/org.apache.sis.storage.xml/test/org/apache/sis/storage/gpx/ReaderTest.java
index 5f539c9a1c..86cd129697 100644
--- 
a/endorsed/src/org.apache.sis.storage.xml/test/org/apache/sis/storage/gpx/ReaderTest.java
+++ 
b/endorsed/src/org.apache.sis.storage.xml/test/org/apache/sis/storage/gpx/ReaderTest.java
@@ -34,7 +34,6 @@ import org.apache.sis.storage.gps.Fix;
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.apache.sis.test.Assertions.assertSingletonFeature;
-import static org.apache.sis.test.TestUtilities.date;
 import org.apache.sis.test.TestCase;
 
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
@@ -155,14 +154,14 @@ public final class ReaderTest extends TestCase {
      */
     @SuppressWarnings("fallthrough")
     static void verifyMetadata(final Metadata md, final int numLinks) {
-        assertEquals      ("Sample",                            md.name);
-        assertEquals      ("GPX test file",                     
md.description);
-        assertEquals      (date("2010-03-01 00:00:00"),         md.time);
-        assertArrayEquals (new String[] {"sample", "metadata"}, 
md.keywords.toArray());
-        assertBoundsEquals(-20, 30, 10, 40,                     md.bounds);
-        assertEquals      ("Jean-Pierre",                       
md.author.name);
-        assertEquals      ("[email protected]",              
md.author.email);
-        assertEquals      (numLinks,                            
md.links.size());
+        assertEquals      ("Sample",                              md.name);
+        assertEquals      ("GPX test file",                       
md.description);
+        assertEquals      (Instant.parse("2010-03-01T00:00:00Z"), 
md.time.toInstant());
+        assertArrayEquals (new String[] {"sample", "metadata"},   
md.keywords.toArray());
+        assertBoundsEquals(-20, 30, 10, 40,                       md.bounds);
+        assertEquals      ("Jean-Pierre",                         
md.author.name);
+        assertEquals      ("[email protected]",                
md.author.email);
+        assertEquals      (numLinks,                              
md.links.size());
         switch (numLinks) {
             default: // Fallthrough everywhere.
             case 3:  assertStringEquals("website",                   
md.links.get(2).type);
diff --git 
a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/csv/StoreTest.java
 
b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/csv/StoreTest.java
index 51648e8414..b2493af31a 100644
--- 
a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/csv/StoreTest.java
+++ 
b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/csv/StoreTest.java
@@ -36,7 +36,6 @@ import org.apache.sis.setup.GeometryLibrary;
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import org.apache.sis.test.TestCase;
-import static org.apache.sis.test.TestUtilities.date;
 import static org.apache.sis.test.Assertions.assertSingletonBBox;
 import static org.apache.sis.test.Assertions.assertSingletonExtent;
 
@@ -83,7 +82,7 @@ public final class StoreTest extends TestCase {
      * Returns the instant for the given time at the day of the test.
      */
     private static Instant instant(final String time) {
-        return date("2012-01-17 " + time).toInstant();
+        return Instant.parse("2012-01-17T" + time + 'Z');
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/converter/InstantConverter.java
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/converter/InstantConverter.java
index d49b6c9bf0..3d17ee4f7f 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/converter/InstantConverter.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/converter/InstantConverter.java
@@ -77,6 +77,7 @@ abstract class InstantConverter<T> extends 
SystemConverter<Instant,T> {
         }
 
         @Override public java.util.Date apply(final Instant source) {
+            // TODO: after merge of `util` with `metadata`: return 
TemporalDate.toDate(source);
             return (source != null) ? java.util.Date.from(source) : null;
         }
     }
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/RangeFormat.java 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/RangeFormat.java
index 8ddd83c54d..ad0335cda0 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/RangeFormat.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/RangeFormat.java
@@ -961,6 +961,7 @@ public class RangeFormat extends Format implements 
Localized {
                     c = source.codePointAt(index);
                     if (!Character.isWhitespace(c)) break;
                 }
+                @SuppressWarnings("LocalVariableHidesMemberVariable")
                 final String separator = this.separator;
                 if (source.startsWith(separator, index)) {
                     index += separator.length();
diff --git 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/AngleFormatTest.java
 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/AngleFormatTest.java
index 9bc9920e9f..f0407f48bf 100644
--- 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/AngleFormatTest.java
+++ 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/AngleFormatTest.java
@@ -27,7 +27,6 @@ import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.apache.sis.test.Assertions.assertMessageContains;
 import org.apache.sis.test.TestCase;
-import static org.apache.sis.test.TestUtilities.*;
 
 
 /**
@@ -35,6 +34,7 @@ import static org.apache.sis.test.TestUtilities.*;
  *
  * @author  Martin Desruisseaux (MPO, IRD, Geomatys)
  */
+@SuppressWarnings("exports")
 public final class AngleFormatTest extends TestCase {
     /**
      * Creates a new test case.
@@ -42,12 +42,32 @@ public final class AngleFormatTest extends TestCase {
     public AngleFormatTest() {
     }
 
+    /**
+     * Formats the given value using the given formatter, and parses the text 
back to its value.
+     * If the parsed value is not equal to the original one, an {@link 
AssertionError} is thrown.
+     *
+     * @param  formatter  the formatter to use for formatting and parsing.
+     * @param  value      the value to format.
+     * @return the formatted value.
+     */
+    private static String formatAndParse(final AngleFormat formatter, final 
Object value) {
+        final String text = formatter.format(value);
+        final Object parsed;
+        try {
+            parsed = formatter.parseObject(text);
+        } catch (ParseException e) {
+            throw new AssertionError(e);
+        }
+        assertEquals(value, parsed, "Parsed text not equal to the original 
value");
+        return text;
+    }
+
     /**
      * Tests a pattern with illegal usage of D, M and S symbols.
      */
     @Test
     public void testIllegalPattern() {
-        final AngleFormat f = new AngleFormat(Locale.CANADA);
+        final var f = new AngleFormat(Locale.CANADA);
         var e = assertThrows(IllegalArgumentException.class, () -> 
f.applyPattern("DD°SS′MM″"));
         assertMessageContains(e);
     }
@@ -56,7 +76,7 @@ public final class AngleFormatTest extends TestCase {
      * Tests an illegal pattern with illegal symbols for the fraction part.
      */
     public void testIllegalFractionPattern() {
-        final AngleFormat f = new AngleFormat(Locale.CANADA);
+        final var f = new AngleFormat(Locale.CANADA);
         var e = assertThrows(IllegalArgumentException.class, () -> 
f.applyPattern("DD°MM′SS.m″"));
         assertMessageContains(e);
     }
@@ -66,7 +86,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testIllegalOptionalField() {
-        final AngleFormat f = new AngleFormat(Locale.CANADA);
+        final var f = new AngleFormat(Locale.CANADA);
         var e = assertThrows(IllegalArgumentException.class, () -> 
f.applyPattern("DD°MM?SS.m″"));
         assertMessageContains(e);
     }
@@ -76,7 +96,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testIllegalOptionalLastField() {
-        final AngleFormat f = new AngleFormat(Locale.CANADA);
+        final var f = new AngleFormat(Locale.CANADA);
         var e = assertThrows(IllegalArgumentException.class, () -> 
f.applyPattern("DD°MM?"));
         assertMessageContains(e);
     }
@@ -86,7 +106,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testCanadaLocale() {
-        final AngleFormat f = new AngleFormat("DD.ddd°", Locale.CANADA);
+        final var f = new AngleFormat("DD.ddd°", Locale.CANADA);
         assertEquals(3, f.getMinimumFractionDigits());
         assertEquals(3, f.getMaximumFractionDigits());
         assertEquals( "DD.ddd°",  f.toPattern());
@@ -103,7 +123,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testFranceLocale() {
-        final AngleFormat f = new AngleFormat("DD.ddd°", Locale.FRANCE);
+        final var f = new AngleFormat("DD.ddd°", Locale.FRANCE);
         assertEquals(3, f.getMinimumFractionDigits());
         assertEquals(3, f.getMaximumFractionDigits());
         assertEquals( "DD.ddd°",  f.toPattern());
@@ -117,7 +137,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testNoSeparator() {
-        final AngleFormat f = new AngleFormat("DDddd", Locale.CANADA);
+        final var f = new AngleFormat("DDddd", Locale.CANADA);
         assertEquals(3, f.getMinimumFractionDigits());
         assertEquals(3, f.getMaximumFractionDigits());
         assertEquals( "DDddd",  f.toPattern());
@@ -131,7 +151,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testDegreeMinutes() {
-        final AngleFormat f = new AngleFormat("DD°MM.m", Locale.CANADA);
+        final var f = new AngleFormat("DD°MM.m", Locale.CANADA);
         assertEquals(1, f.getMinimumFractionDigits());
         assertEquals(1, f.getMaximumFractionDigits());
         assertEquals( "DD°MM.m", f.toPattern());
@@ -146,7 +166,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testDegreeMinutesSeconds() {
-        final AngleFormat f = new AngleFormat("DD°MM′SS.sss″", Locale.CANADA);
+        final var f = new AngleFormat("DD°MM′SS.sss″", Locale.CANADA);
         assertEquals(3, f.getMinimumFractionDigits());
         assertEquals(3, f.getMaximumFractionDigits());
         assertEquals( "DD°MM′SS.sss″", f.toPattern());
@@ -161,7 +181,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testRounding() {
-        final AngleFormat f = new AngleFormat("DD°MM′SS.sss″", Locale.CANADA);
+        final var f = new AngleFormat("DD°MM′SS.sss″", Locale.CANADA);
         assertEquals( "01°00′00.000″", f.format(new Angle(+(59 + (59.9999 / 
60)) / 60)));
         assertEquals("-01°00′00.000″", f.format(new Angle(-(59 + (59.9999 / 
60)) / 60)));
         assertEquals("-00°59′59.999″", f.format(new Angle(-(59 + (59.9988 / 
60)) / 60)));
@@ -172,7 +192,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testOptionalFields() {
-        final AngleFormat f = new AngleFormat(Locale.CANADA);
+        final var f = new AngleFormat(Locale.CANADA);
         assertEquals("D°?MM′?SS.################″?", f.toPattern());
         assertEquals("12°",          formatAndParse(f, new Angle(12)));
         assertEquals("12°30′",       formatAndParse(f, new Angle(12.5)));
@@ -190,7 +210,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testJavadocExamples() throws ParseException {
-        final AngleFormat f = new AngleFormat(Locale.CANADA);
+        final var f = new AngleFormat(Locale.CANADA);
         testExample(f, "DD°MM′SS.#″",   "48°30′00″", "-12°31′52.5″", 0.000);
         testExample(f, "DD°MM′",        "48°30′",    "-12°32′",      0.003);
         testExample(f, "DD.ddd",        "48.500",    "-12.531",      2.500);
@@ -225,7 +245,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testRoundingMode() {
-        final AngleFormat f = new AngleFormat("DD°MM′SS″", Locale.CANADA);
+        final var f = new AngleFormat("DD°MM′SS″", Locale.CANADA);
         Angle angle = new Angle(12.515625);
         f.setRoundingMode(RoundingMode.DOWN);      assertEquals("12°30′56″", 
f.format(angle));
         f.setRoundingMode(RoundingMode.UP);        assertEquals("12°30′57″", 
f.format(angle));
@@ -246,7 +266,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testOptionalFractionDigits() {
-        final AngleFormat f = new AngleFormat("DD°MM′SS.s##″", Locale.CANADA);
+        final var f = new AngleFormat("DD°MM′SS.s##″", Locale.CANADA);
         assertEquals(1, f.getMinimumFractionDigits());
         assertEquals(3, f.getMaximumFractionDigits());
         assertEquals( "DD°MM′SS.s##″", f.toPattern());
@@ -270,7 +290,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testSetMaximumWidth() {
-        final AngleFormat f = new AngleFormat("D°MM′SS.################″", 
Locale.CANADA);
+        final var f = new AngleFormat("D°MM′SS.################″", 
Locale.CANADA);
         assertEquals("D°MM′SS.################″", f.toPattern());
 
         f.setMaximumWidth(12);
@@ -318,7 +338,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testSetPrecision() {
-        final AngleFormat f = new AngleFormat(Locale.CANADA);
+        final var f = new AngleFormat(Locale.CANADA);
         f.setPrecision(1,        true); assertEquals("D°",         
f.toPattern());
         f.setPrecision(1./10,    true); assertEquals("D.d°",       
f.toPattern());
         f.setPrecision(1./60,    true); assertEquals("D°MM′",      
f.toPattern());
@@ -338,7 +358,7 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testGetPrecision() {
-        final AngleFormat f = new AngleFormat(Locale.CANADA);
+        final var f = new AngleFormat(Locale.CANADA);
         f.applyPattern("D°");         assertEquals(     1,   f.getPrecision());
         f.applyPattern("D.dd°");      assertEquals(  0.01,   f.getPrecision(), 
 1E-16);
         f.applyPattern("D°MM′");      assertEquals(1.0/60,   f.getPrecision(), 
 1E-16);
@@ -350,9 +370,9 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testFieldPosition() {
-        final Latitude latitude = new 
Latitude(FormattedCharacterIteratorTest.LATITUDE_VALUE);
-        final AngleFormat f = new AngleFormat("DD°MM′SS.s″", Locale.CANADA);
-        final StringBuffer buffer = new StringBuffer();
+        final var latitude = new 
Latitude(FormattedCharacterIteratorTest.LATITUDE_VALUE);
+        final var f = new AngleFormat("DD°MM′SS.s″", Locale.CANADA);
+        final var buffer = new StringBuffer();
         for (int i=AngleFormat.DEGREES_FIELD; i<=AngleFormat.HEMISPHERE_FIELD; 
i++) {
             final AngleFormat.Field field;
             final int start, limit;
@@ -363,7 +383,7 @@ public final class AngleFormatTest extends TestCase {
                 case AngleFormat.HEMISPHERE_FIELD: field = 
AngleFormat.Field.HEMISPHERE; start=11; limit=12; break;
                 default: continue; // Skip the fraction field.
             }
-            final FieldPosition pos = new FieldPosition(field);
+            final var pos = new FieldPosition(field);
             assertEquals(FormattedCharacterIteratorTest.LATITUDE_STRING, 
f.format(latitude, buffer, pos).toString());
             assertSame  (field, pos.getFieldAttribute());
             assertEquals(start, pos.getBeginIndex());
@@ -377,8 +397,8 @@ public final class AngleFormatTest extends TestCase {
      */
     @Test
     public void testFormatToCharacterIterator() {
-        final Latitude latitude = new 
Latitude(FormattedCharacterIteratorTest.LATITUDE_VALUE);
-        final AngleFormat f = new AngleFormat("DD°MM′SS.s″", Locale.CANADA);
+        final var latitude = new 
Latitude(FormattedCharacterIteratorTest.LATITUDE_VALUE);
+        final var f = new AngleFormat("DD°MM′SS.s″", Locale.CANADA);
         final AttributedCharacterIterator it = 
f.formatToCharacterIterator(latitude);
         assertEquals(FormattedCharacterIteratorTest.LATITUDE_STRING, 
it.toString());
         FormattedCharacterIteratorTest.testAttributes(it, true);
diff --git 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/DateRangeTest.java
 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/DateRangeTest.java
index 00642d6d29..c7e39fe543 100644
--- 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/DateRangeTest.java
+++ 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/DateRangeTest.java
@@ -16,22 +16,20 @@
  */
 package org.apache.sis.measure;
 
-import java.util.Date;
+import java.time.Instant;
 
 // Test dependencies
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import org.apache.sis.test.TestCase;
-import static org.apache.sis.test.TestUtilities.date;
 
 
 /**
- * Tests the {@link Range} class with date values. A previous version was 
using a dedicated
- * {@code DateRange} for this purpose. However, the specialized class has been 
removed because
- * usage of {@code java.util.Date} is replaced by usage of ISO 19108 (temporal 
schema) types.
+ * Tests the {@link Range} class with temporal values.
  *
  * @author  Martin Desruisseaux (IRD)
  */
+@SuppressWarnings("exports")
 public final class DateRangeTest extends TestCase {
     /**
      * Creates a new test case.
@@ -44,21 +42,21 @@ public final class DateRangeTest extends TestCase {
      */
     @Test
     public void testUnion() {
-        final Date min = date("1998-04-02 13:00:00");
-        final Date in1 = date("1998-05-12 11:00:00");
-        final Date in2 = date("1998-06-08 14:00:00");
-        final Date max = date("1998-07-01 19:00:00");
-        final Range<Date> r1 = new Range<>(Date.class, min, true, in2, true);
-        final Range<Date> r2 = new Range<>(Date.class, in1, true, max, true);
-        final Range<Date> rt = r1.union(r2);
+        final Instant min = Instant.parse("1998-04-02T13:00:00Z");
+        final Instant in1 = Instant.parse("1998-05-12T11:00:00Z");
+        final Instant in2 = Instant.parse("1998-06-08T14:00:00Z");
+        final Instant max = Instant.parse("1998-07-01T19:00:00Z");
+        final Range<Instant> r1 = new Range<>(Instant.class, min, true, in2, 
true);
+        final Range<Instant> r2 = new Range<>(Instant.class, in1, true, max, 
true);
+        final Range<Instant> rt = r1.union(r2);
         assertEquals(min, rt.getMinValue());
         assertEquals(max, rt.getMaxValue());
         assertEquals(rt, r2.union(r1));
         /*
          * Test a range fully included in the other range.
          */
-        final Range<Date> outer = new Range<>(Date.class, min, true, max, 
true);
-        final Range<Date> inner = new Range<>(Date.class, in1, true, in2, 
true);
+        final Range<Instant> outer = new Range<>(Instant.class, min, true, 
max, true);
+        final Range<Instant> inner = new Range<>(Instant.class, in1, true, 
in2, true);
         assertSame(outer, outer.union(inner));
         assertSame(outer, inner.union(outer));
     }
@@ -68,21 +66,21 @@ public final class DateRangeTest extends TestCase {
      */
     @Test
     public void testIntersect() {
-        final Date min = date("1998-04-02 13:00:00");
-        final Date in1 = date("1998-05-12 11:00:00");
-        final Date in2 = date("1998-06-08 14:00:00");
-        final Date max = date("1998-07-01 19:00:00");
-        final Range<Date> r1 = new Range<>(Date.class, min, true, in2, true);
-        final Range<Date> r2 = new Range<>(Date.class, in1, true, max, true);
-        final Range<Date> rt = r1.intersect(r2);
+        final Instant min = Instant.parse("1998-04-02T13:00:00Z");
+        final Instant in1 = Instant.parse("1998-05-12T11:00:00Z");
+        final Instant in2 = Instant.parse("1998-06-08T14:00:00Z");
+        final Instant max = Instant.parse("1998-07-01T19:00:00Z");
+        final Range<Instant> r1 = new Range<>(Instant.class, min, true, in2, 
true);
+        final Range<Instant> r2 = new Range<>(Instant.class, in1, true, max, 
true);
+        final Range<Instant> rt = r1.intersect(r2);
         assertEquals(in1, rt.getMinValue());
         assertEquals(in2, rt.getMaxValue());
         assertEquals(rt, r2.intersect(r1));
         /*
          * Test a range fully included in the other range.
          */
-        final Range<Date> outer = new Range<>(Date.class, min, true, max, 
true);
-        final Range<Date> inner = new Range<>(Date.class, in1, true, in2, 
true);
+        final Range<Instant> outer = new Range<>(Instant.class, min, true, 
max, true);
+        final Range<Instant> inner = new Range<>(Instant.class, in1, true, 
in2, true);
         assertSame(inner, outer.intersect(inner));
         assertSame(inner, inner.intersect(outer));
     }
@@ -92,13 +90,13 @@ public final class DateRangeTest extends TestCase {
      */
     @Test
     public void testSubtract() {
-        final Date min = date("1998-04-02 13:00:00");
-        final Date in1 = date("1998-05-12 11:00:00");
-        final Date in2 = date("1998-06-08 14:00:00");
-        final Date max = date("1998-07-01 19:00:00");
-        final Range<Date> outer = new Range<>(Date.class, min, true, max, 
true);
-        final Range<Date> inner = new Range<>(Date.class, in1, true, in2, 
true);
-        final Range<Date>[] rt = outer.subtract(inner);
+        final Instant min = Instant.parse("1998-04-02T13:00:00Z");
+        final Instant in1 = Instant.parse("1998-05-12T11:00:00Z");
+        final Instant in2 = Instant.parse("1998-06-08T14:00:00Z");
+        final Instant max = Instant.parse("1998-07-01T19:00:00Z");
+        final Range<Instant> outer = new Range<>(Instant.class, min, true, 
max, true);
+        final Range<Instant> inner = new Range<>(Instant.class, in1, true, 
in2, true);
+        final Range<Instant>[] rt = outer.subtract(inner);
         assertEquals(2, rt.length);
         assertEquals(min, rt[0].getMinValue());
         assertEquals(in1, rt[0].getMaxValue());
diff --git 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/test/TestUtilities.java 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/test/TestUtilities.java
index fde3b6a0b1..9cca448c5a 100644
--- 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/test/TestUtilities.java
+++ 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/test/TestUtilities.java
@@ -16,9 +16,6 @@
  */
 package org.apache.sis.test;
 
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
 import java.util.Random;
 import java.io.IOException;
 import java.io.InputStream;
@@ -29,18 +26,7 @@ import java.nio.file.StandardOpenOption;
 import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.SeekableByteChannel;
-import java.lang.reflect.UndeclaredThrowableException;
-import java.text.Format;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
 import org.apache.sis.util.Debug;
-import org.apache.sis.util.CharSequences;
-import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.collection.TreeTable;
-import org.apache.sis.util.collection.TableColumn;
-import org.apache.sis.util.collection.TreeTableFormat;
-import static org.apache.sis.util.internal.shared.Constants.UTC;
 
 // Test dependencies
 import static org.junit.jupiter.api.Assertions.*;
@@ -52,23 +38,6 @@ import static org.junit.jupiter.api.Assertions.*;
  * @author  Martin Desruisseaux (Geomatys)
  */
 public final class TestUtilities {
-    /**
-     * Date parser and formatter using the {@code "yyyy-MM-dd HH:mm:ss"} 
pattern
-     * and UTC time zone.
-     */
-    private static final DateFormat dateFormat;
-    static {
-        dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", 
Locale.CANADA);
-        dateFormat.setTimeZone(TimeZone.getTimeZone(UTC));
-        dateFormat.setLenient(false);
-    };
-
-    /**
-     * The {@link TreeTableFormat} to use for unlocalized string 
representations.
-     * Created when first needed.
-     */
-    private static Format tableFormat;
-
     /**
      * The thread group for every threads created for testing purpose.
      */
@@ -141,121 +110,9 @@ public final class TestUtilities {
         return new Random(seed);
     }
 
-    /**
-     * Parses the date for the given string using the {@code "yyyy-MM-dd 
HH:mm:ss"} pattern in UTC timezone.
-     *
-     * @param  date  the date as a {@link String}.
-     * @return the date as a {@link Date}.
-     *
-     * @todo Remove in favor of {@link java.time.Instant#parse}.
-     */
-    public static Date date(final String date) {
-        ArgumentChecks.ensureNonNull("date", date);
-        final Date t;
-        try {
-            synchronized (dateFormat) {
-                t = dateFormat.parse(date);
-            }
-        } catch (ParseException e) {
-            throw new AssertionError(e);
-        }
-        /*
-         * The milliseconds are not part of the pattern used by this method 
because they are rarely specified.
-         * If a test needs to specify milliseconds, add them manually here. 
Note that this naive hack requires
-         * all milliseconds digits to be provided, e.g. ".900" - not ".9".
-         */
-        final int s = date.lastIndexOf('.');
-        if (s >= 0) {
-            final int ms = Integer.parseInt(date.substring(s + 1));
-            t.setTime(t.getTime() + ms);
-        }
-        return t;
-    }
-
-    /**
-     * Formats the given value using the given formatter, and parses the text 
back to its value.
-     * If the parsed value is not equal to the original one, an {@link 
AssertionError} is thrown.
-     *
-     * @param  formatter  the formatter to use for formatting and parsing.
-     * @param  value      the value to format.
-     * @return the formatted value.
-     */
-    public static String formatAndParse(final Format formatter, final Object 
value) {
-        final String text = formatter.format(value);
-        final Object parsed;
-        try {
-            parsed = formatter.parseObject(text);
-        } catch (ParseException e) {
-            throw new AssertionError(e);
-        }
-        assertEquals(value, parsed, "Parsed text not equal to the original 
value");
-        return text;
-    }
-
-    /**
-     * Returns a unlocalized string representation of {@code NAME}, {@code 
VALUE} and {@code REMARKS} columns
-     * of the given tree table. They are the columns included in default 
string representation of metadata.
-     * Dates and times, if any, will be formatted using the {@code "yyyy-MM-dd 
HH:mm:ss"} pattern in UTC timezone.
-     * This method is used mostly as a convenient way to verify the content of 
an ISO 19115 metadata object.
-     *
-     * @param  table  the table for which to get a string representation.
-     * @return a unlocalized string representation of the given tree table.
-     */
-    public static String formatMetadata(final TreeTable table) {
-        synchronized (TestUtilities.class) {
-            if (tableFormat == null) {
-                final TreeTableFormat f = new TreeTableFormat(null, null);
-                f.setColumns(TableColumn.NAME, TableColumn.VALUE, 
TableColumn.REMARKS);
-                tableFormat = f;
-            }
-            return tableFormat.format(table);
-        }
-    }
-
-    /**
-     * Returns the tree structure of the given string representation, without 
the localized text.
-     * For example, given the following string:
-     *
-     * <pre class="text">
-     *   Citation
-     *     ├─Title…………………………………………………… Some title
-     *     └─Cited responsible party
-     *         └─Individual name……………… Some person of contact</pre>
-     *
-     * this method returns an array containing the following elements:
-     *
-     * <pre class="text">
-     *   "",
-     *   "  ├─",
-     *   "  └─",
-     *   "      └─"</pre>
-     *
-     * This method is used for comparing two trees having string 
representation in different locales.
-     * In such case, we cannot compare the actual text content. The best we 
can do is to compare
-     * the tree structure.
-     *
-     * @param  tree  the string representation of a tree.
-     * @return the structure of the given tree, without text.
-     */
-    public static CharSequence[] toTreeStructure(final CharSequence tree) {
-        final CharSequence[] lines = CharSequences.split(tree, '\n');
-        for (int i=0; i<lines.length; i++) {
-            final CharSequence line = lines[i];
-            final int length = line.length();
-            for (int j=0; j<length;) {
-                final int c = Character.codePointAt(line, j);
-                if (Character.isLetterOrDigit(c)) {
-                    lines[i] = line.subSequence(0, j);
-                    break;
-                }
-                j += Character.charCount(c);
-            }
-        }
-        return lines;
-    }
-
     /**
      * Returns a copy of the given array with the last coordinate values 
dropped for each coordinates.
+     * The array can contain many points, with an array length equals to a 
multiple of {@code sourceDim}.
      *
      * @param  coordinates  the source coordinates from which to drop the last 
coordinate values.
      * @param  sourceDim    number of dimensions of each point in the {@code 
coordinates} array.
@@ -272,20 +129,6 @@ public final class TestUtilities {
         return reduced;
     }
 
-    /**
-     * If the given failure is not null, re-thrown it as an {@link Error} or
-     * {@link RuntimeException}. Otherwise do nothing.
-     *
-     * @param  failure  the exception to re-thrown if non-null.
-     */
-    public static void rethrownIfNotNull(final Throwable failure) {
-        if (failure != null) {
-            if (failure instanceof Error e) throw e;
-            if (failure instanceof RuntimeException e) throw e;
-            throw new UndeclaredThrowableException(failure);
-        }
-    }
-
     /**
      * Copies the full content of the given input stream in a temporary file 
and returns the channel for that file.
      * The file is opened with {@link StandardOpenOption#DELETE_ON_CLOSE}, 
together with read and write options.
diff --git 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/test/self/TestUtilitiesTest.java
 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/test/self/TestUtilitiesTest.java
deleted file mode 100644
index 2dd0b8ef27..0000000000
--- 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/test/self/TestUtilitiesTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-package org.apache.sis.test.self;
-
-// Test dependencies
-import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.*;
-import org.apache.sis.test.TestCase;
-import org.apache.sis.test.TestUtilities;
-
-
-/**
- * Tests the {@link org.apache.sis.test.TestUtilities} class.
- *
- * @author  Martin Desruisseaux (Geomatys)
- */
-public final class TestUtilitiesTest extends TestCase {
-    /**
-     * Creates a new test case.
-     */
-    public TestUtilitiesTest() {
-    }
-
-    /**
-     * Tests {@link 
org.apache.sis.test.TestUtilities#toTreeStructure(CharSequence)}.
-     */
-    @Test
-    public void testToTreeStructure() {
-        assertArrayEquals(new CharSequence[] {
-            "",
-            "  ├─",
-            "  ├─",
-            "  │   ├─",
-            "  │   └─",
-            "  └─",
-            ""
-            }, TestUtilities.toTreeStructure(
-            "DefaultCitation\n" +
-            "  ├─Title…………………………………………………………… Some title\n" +
-            "  ├─Cited responsible party\n" +
-            "  │   ├─Individual name……………………… Some person of contact\n" +
-            "  │   └─Role…………………………………………………… Point of contact\n" +
-            "  └─Other citation details……………… Some other details\n"));
-    }
-}
diff --git 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/collection/CacheTest.java
 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/collection/CacheTest.java
index 717ab32b99..84b3d4d2a3 100644
--- 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/collection/CacheTest.java
+++ 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/collection/CacheTest.java
@@ -22,6 +22,7 @@ import java.util.Map;
 import java.util.HashMap;
 import java.util.AbstractMap.SimpleEntry;
 import java.util.concurrent.atomic.AtomicReference;
+import java.lang.reflect.UndeclaredThrowableException;
 import java.io.IOException;
 import java.io.UncheckedIOException;
 import static java.lang.StrictMath.*;
@@ -169,7 +170,7 @@ public final class CacheTest extends TestCaseWithGC {
          */
         handler.putAndUnlock(valueByMainThread);
         thread.join();
-        TestUtilities.rethrownIfNotNull(thread.failure);
+        rethrownIfNotNull(thread.failure);
         /*
          * Checks the map content.
          */
@@ -179,6 +180,20 @@ public final class CacheTest extends TestCaseWithGC {
         assertMapEquals(expected, cache);
     }
 
+    /**
+     * If the given failure is not null, re-thrown it as an {@link Error}
+     * or {@link RuntimeException}. Otherwise, does nothing.
+     *
+     * @param  failure  the exception to re-thrown if non-null.
+     */
+    private static void rethrownIfNotNull(final Throwable failure) {
+        if (failure != null) {
+            if (failure instanceof Error e) throw e;
+            if (failure instanceof RuntimeException e) throw e;
+            throw new UndeclaredThrowableException(failure);
+        }
+    }
+
     /**
      * Validates the entries created by the {@link #stress()} test. The check 
performed in
      * this method shall obviously be consistent with the values created by 
{@code stress()}.
@@ -257,7 +272,7 @@ public final class CacheTest extends TestCaseWithGC {
         for (WriterThread thread : threads) {
             thread.join();
         }
-        TestUtilities.rethrownIfNotNull(failures.get());
+        rethrownIfNotNull(failures.get());
         /*
          * Verifies the values.
          */

Reply via email to