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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new c6b08e544d More replacements of `java.util.Date` by `java.time` in 
metadata.
c6b08e544d is described below

commit c6b08e544da8b318b69d1a62453adebc090e8598
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Jun 6 19:52:17 2024 +0200

    More replacements of `java.util.Date` by `java.time` in metadata.
---
 .../sis/metadata/internal/CitationConstant.java    |  4 +-
 .../apache/sis/metadata/iso/DefaultMetadata.java   | 32 +++++++--
 .../sis/metadata/iso/acquisition/DefaultEvent.java | 32 ++++++---
 .../iso/acquisition/DefaultRequestedDate.java      | 58 ++++++++++++---
 .../iso/acquisition/DefaultRequirement.java        | 30 ++++++--
 .../sis/metadata/iso/acquisition/package-info.java |  2 +-
 .../sis/metadata/iso/citation/DefaultCitation.java | 31 ++++++--
 .../metadata/iso/citation/DefaultCitationDate.java | 36 +++++++---
 .../sis/metadata/iso/citation/package-info.java    |  2 +-
 .../distribution/DefaultStandardOrderProcess.java  | 42 +++++++++--
 .../metadata/iso/distribution/package-info.java    |  2 +-
 .../metadata/iso/identification/DefaultUsage.java  | 83 +++++++++++++++++++---
 .../sis/metadata/iso/quality/AbstractResult.java   |  6 +-
 .../sis/pending/temporal/TemporalUtilities.java    |  8 +--
 .../apache/sis/metadata/PropertyAccessorTest.java  |  4 +-
 .../apache/sis/metadata/TreeNodeChildrenTest.java  |  6 +-
 .../test/org/apache/sis/metadata/TypeMapTest.java  |  4 +-
 .../iso/citation/DefaultCitationDateTest.java      | 11 +--
 .../metadata/iso/citation/DefaultCitationTest.java |  9 +--
 .../DefaultDataIdentificationTest.java             |  5 +-
 .../sis/xml/test/AnnotationConsistencyCheck.java   |  7 ++
 .../sis/referencing/datum/AbstractDatum.java       |  4 +-
 .../sis/storage/landsat/MetadataReaderTest.java    |  9 +--
 .../sis/storage/netcdf/MetadataReaderTest.java     | 30 ++++++--
 .../apache/sis/storage/netcdf/NetcdfStoreTest.java |  2 +-
 .../main/org/apache/sis/storage/gpx/Copyright.java | 12 ++--
 .../apache/sis/storage/base/MetadataBuilder.java   |  2 +-
 .../main/org/apache/sis/io/CompoundFormat.java     | 66 +++++++++++++++--
 .../sis/util/collection/TreeTableFormat.java       |  7 +-
 geoapi/snapshot                                    |  2 +-
 30 files changed, 430 insertions(+), 118 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/CitationConstant.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/CitationConstant.java
index 7b2c089edf..b603e2f9bb 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/CitationConstant.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/CitationConstant.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.metadata.internal;
 
-import java.util.Date;
 import java.util.Collection;
 import java.util.logging.Logger;
 import java.io.ObjectStreamException;
@@ -40,6 +39,7 @@ import org.opengis.metadata.citation.OnlineResource;
 import org.opengis.metadata.identification.BrowseGraphic;
 
 // Specific to the geoapi-4.0 branch:
+import java.time.temporal.Temporal;
 import org.opengis.metadata.citation.Responsibility;
 
 
@@ -215,7 +215,7 @@ public class CitationConstant extends SimpleCitation {
     @Override public Collection<? extends InternationalString>  
getAlternateTitles()         {return delegate().getAlternateTitles();}
     @Override public Collection<? extends CitationDate>         getDates()     
              {return delegate().getDates();}
     @Override public InternationalString                        getEdition()   
              {return delegate().getEdition();}
-    @Override public Date                                       
getEditionDate()             {return delegate().getEditionDate();}
+    @Override public Temporal                                   
getEditionDate()             {return delegate().getEditionDate();}
     @Override public Collection<? extends Identifier>           
getIdentifiers()             {return delegate().getIdentifiers();}
     @Override public Collection<? extends Responsibility>       
getCitedResponsibleParties() {return delegate().getCitedResponsibleParties();}
     @Override public Collection<PresentationForm>               
getPresentationForms()       {return delegate().getPresentationForms();}
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/DefaultMetadata.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/DefaultMetadata.java
index 408a767da6..d9265feb93 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/DefaultMetadata.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/DefaultMetadata.java
@@ -28,6 +28,7 @@ import java.util.Iterator;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.nio.charset.Charset;
+import java.time.temporal.Temporal;
 import jakarta.xml.bind.Marshaller;
 import jakarta.xml.bind.annotation.XmlType;
 import jakarta.xml.bind.annotation.XmlSeeAlso;
@@ -59,6 +60,9 @@ import org.opengis.util.InternationalString;
 import org.apache.sis.util.SimpleInternationalString;
 import org.apache.sis.util.Emptiable;
 import org.apache.sis.util.ObjectConverter;
+import org.apache.sis.util.collection.Containers;
+import org.apache.sis.util.privy.CollectionsExt;
+import org.apache.sis.util.privy.TemporalDate;
 import org.apache.sis.metadata.MetadataCopier;
 import org.apache.sis.metadata.MetadataStandard;
 import org.apache.sis.metadata.iso.citation.DefaultCitation;
@@ -69,7 +73,6 @@ import 
org.apache.sis.metadata.iso.identification.DefaultDataIdentification;
 import org.apache.sis.metadata.iso.legacy.LegacyPropertyAdapter;
 import org.apache.sis.metadata.privy.ImplementationHelper;
 import org.apache.sis.metadata.internal.Dependencies;
-import org.apache.sis.util.privy.CollectionsExt;
 import org.apache.sis.xml.bind.FilterByVersion;
 import org.apache.sis.xml.bind.Context;
 import org.apache.sis.xml.bind.lan.LocaleAndCharset;
@@ -79,7 +82,6 @@ import org.apache.sis.xml.bind.lan.PT_Locale;
 import org.apache.sis.xml.bind.metadata.CI_Citation;
 import org.apache.sis.xml.bind.metadata.MD_Identifier;
 import org.apache.sis.xml.privy.LegacyNamespaces;
-import org.apache.sis.util.collection.Containers;
 import org.apache.sis.converter.SurjectiveConverter;
 import org.apache.sis.math.FunctionProperty;
 
@@ -352,10 +354,30 @@ public class DefaultMetadata extends ISOMetadata 
implements Metadata {
      * @param contact             party responsible for the metadata 
information.
      * @param dateStamp           date that the metadata was created.
      * @param identificationInfo  basic information about the resource to 
which the metadata applies.
+     *
+     * @deprecated Replaced by {@link #DefaultMetadata(Responsibility, 
Temporal, Identification)}.
      */
+    @Deprecated(since="1.5", forRemoval=true)
     public DefaultMetadata(final Responsibility contact,
                            final Date           dateStamp,
                            final Identification identificationInfo)
+    {
+        this(contact, TemporalDate.toTemporal(dateStamp), identificationInfo);
+    }
+
+    /**
+     * Creates a meta data initialized to the specified values.
+     *
+     * @param contact             party responsible for the metadata 
information.
+     * @param dateStamp           date that the metadata was created.
+     * @param identificationInfo  basic information about the resource to 
which the metadata applies.
+     *
+     * @since 1.5
+     */
+    @SuppressWarnings("this-escape")
+    public DefaultMetadata(final Responsibility contact,
+                           final Temporal       dateStamp,
+                           final Identification identificationInfo)
     {
         this.contacts  = singleton(contact, Responsibility.class);
         this.identificationInfo = singleton(identificationInfo, 
Identification.class);
@@ -637,8 +659,7 @@ public class DefaultMetadata extends ISOMetadata implements 
Metadata {
     @XmlJavaTypeAdapter(LocaleAdapter.Wrapped.class)
     public Collection<Locale> getLocales() {
         if (FilterByVersion.LEGACY_METADATA.accept()) {
-            final Set<PT_Locale> locales = 
OtherLocales.filter(getLocalesAndCharsets());
-            return Containers.derivedSet(locales, ToLocale.INSTANCE);
+            return 
Containers.derivedSet(OtherLocales.filter(getLocalesAndCharsets()), 
ToLocale.INSTANCE);
         }
         return null;
     }
@@ -746,6 +767,7 @@ public class DefaultMetadata extends ISOMetadata implements 
Metadata {
     @XmlElement(name = "parentIdentifier", namespace = LegacyNamespaces.GMD)
     public String getParentIdentifier() {
         if (FilterByVersion.LEGACY_METADATA.accept()) {
+            @SuppressWarnings("LocalVariableHidesMemberVariable")
             final Citation parentMetadata = getParentMetadata();
             if (parentMetadata != null) {
                 final InternationalString title = parentMetadata.getTitle();
@@ -1011,7 +1033,7 @@ public class DefaultMetadata extends ISOMetadata 
implements Metadata {
                 }
             }
         }
-        newValues.add(new DefaultCitationDate(newValue, DateType.CREATION));
+        newValues.add(new 
DefaultCitationDate(TemporalDate.toTemporal(newValue), DateType.CREATION));
         setDateInfo(newValues);
     }
 
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultEvent.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultEvent.java
index f318350ada..3f61f355ef 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultEvent.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultEvent.java
@@ -65,7 +65,7 @@ import org.apache.sis.util.privy.TemporalDate;
     "trigger",
     "context",
     "sequence",
-    "time",
+    "dateOfOccurrence",
     "expectedObjectives",
     "relatedPass",
     "relatedSensors"
@@ -139,7 +139,7 @@ public class DefaultEvent extends ISOMetadata implements 
Event {
             trigger            = object.getTrigger();
             context            = object.getContext();
             sequence           = object.getSequence();
-            time               = TemporalDate.toTemporal(object.getTime());
+            time               = object.getDateOfOccurrence();
             expectedObjectives = 
copyCollection(object.getExpectedObjectives(), Objective.class);
             relatedPass        = object.getRelatedPass();
             relatedSensors     = copyCollection(object.getRelatedSensors(), 
Instrument.class);
@@ -258,14 +258,12 @@ public class DefaultEvent extends ISOMetadata implements 
Event {
     /**
      * Returns the time the event occurred.
      *
-     * <div class="warning"><b>Upcoming API change — temporal schema</b><br>
-     * The return type of this method may change in a future version.
-     * It may be replaced by {@link Temporal}.</div>
-     *
      * @return time the event occurred, or {@code null}.
+     *
+     * @deprecated Replaced by {@link #getDateOfOccurrence()}.
      */
     @Override
-    @XmlElement(name = "time", required = true)
+    @Deprecated(since="1.5")
     public Date getTime() {
         return TemporalDate.toDate(time);
     }
@@ -274,9 +272,25 @@ public class DefaultEvent extends ISOMetadata implements 
Event {
      * Sets the time the event occurred.
      *
      * @param  newValue  the new time value.
+     *
+     * @deprecated Replaced by {@link #setDateOfOccurrence(Temporal)}.
      */
+    @Deprecated(since="1.5")
     public void setTime(final Date newValue) {
-        setTime(TemporalDate.toTemporal(newValue));
+        setDateOfOccurrence(TemporalDate.toTemporal(newValue));
+    }
+
+    /**
+     * Returns the time the event occurred.
+     *
+     * @return time the event occurred, or {@code null}.
+     *
+     * @since 1.5
+     */
+    @Override
+    @XmlElement(name = "time", required = true)
+    public Temporal getDateOfOccurrence() {
+        return time;
     }
 
     /**
@@ -286,7 +300,7 @@ public class DefaultEvent extends ISOMetadata implements 
Event {
      *
      * @since 1.5
      */
-    public void setTime(final Temporal newValue) {
+    public void setDateOfOccurrence(final Temporal newValue) {
         checkWritePermission(time);
         time = newValue;
     }
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequestedDate.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequestedDate.java
index d2d4427777..15f26db867 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequestedDate.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequestedDate.java
@@ -45,7 +45,7 @@ import org.apache.sis.util.privy.TemporalDate;
  *
  * @author  Cédric Briançon (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.5
+ * @version 2.0
  * @since   0.3
  */
 @XmlType(name = "MI_RequestedDate_Type", propOrder = {
@@ -89,8 +89,8 @@ public class DefaultRequestedDate extends ISOMetadata 
implements RequestedDate {
     public DefaultRequestedDate(final RequestedDate object) {
         super(object);
         if (object != null) {
-            requestedDateOfCollection = 
TemporalDate.toTemporal(object.getRequestedDateOfCollection());
-            latestAcceptableDate      = 
TemporalDate.toTemporal(object.getLatestAcceptableDate());
+            requestedDateOfCollection = object.getRequestedDateOfCollection();
+            latestAcceptableDate      = object.getLatestAcceptableDate();
         }
     }
 
@@ -123,41 +123,77 @@ public class DefaultRequestedDate extends ISOMetadata 
implements RequestedDate {
      * Returns the preferred date and time of collection.
      *
      * @return preferred date and time, or {@code null}.
+     * @version 2.0
      */
     @Override
     @XmlElement(name = "requestedDateOfCollection", required = true)
-    public Date getRequestedDateOfCollection() {
-        return TemporalDate.toDate(requestedDateOfCollection);
+    public Temporal getRequestedDateOfCollection() {
+        return requestedDateOfCollection;
     }
 
     /**
      * Sets the preferred date and time of collection.
+     * The specified value should be an instance of {@link 
java.time.LocalDate}, {@link java.time.LocalDateTime},
+     * {@link java.time.OffsetDateTime} or {@link java.time.ZonedDateTime}, 
depending whether hours are defined
+     * and how the timezone (if any) is defined. But other types are also 
allowed.
      *
      * @param  newValue  the new requested date of collection value.
+     *
+     * @since 1.5
      */
-    public void setRequestedDateOfCollection(final Date newValue) {
+    public void setRequestedDateOfCollection(final Temporal newValue) {
         checkWritePermission(requestedDateOfCollection);
-        requestedDateOfCollection = TemporalDate.toTemporal(newValue);
+        requestedDateOfCollection = newValue;
+    }
+
+    /**
+     * Sets the preferred date and time of collection.
+     *
+     * @param  newValue  the new requested date of collection value.
+     *
+     * @deprecated Replaced by {@link #setRequestedDateOfCollection(Temporal)}.
+     */
+    @Deprecated(since="1.5")
+    public void setRequestedDateOfCollection(final Date newValue) {
+        setRequestedDateOfCollection(TemporalDate.toTemporal(newValue));
     }
 
     /**
      * Returns the latest date and time collection must be completed.
      *
      * @return latest date and time, or {@code null}.
+     * @version 2.0
      */
     @Override
     @XmlElement(name = "latestAcceptableDate", required = true)
-    public Date getLatestAcceptableDate() {
-        return TemporalDate.toDate(latestAcceptableDate);
+    public Temporal getLatestAcceptableDate() {
+        return latestAcceptableDate;
     }
 
     /**
      * Sets the latest date and time collection must be completed.
+     * The specified value should be an instance of {@link 
java.time.LocalDate}, {@link java.time.LocalDateTime},
+     * {@link java.time.OffsetDateTime} or {@link java.time.ZonedDateTime}, 
depending whether hours are defined
+     * and how the timezone (if any) is defined. But other types are also 
allowed.
      *
      * @param  newValue  the new latest acceptable data value.
+     *
+     * @since 1.5
      */
-    public void setLatestAcceptableDate(final Date newValue) {
+    public void setLatestAcceptableDate(final Temporal newValue) {
         checkWritePermission(latestAcceptableDate);
-        latestAcceptableDate = TemporalDate.toTemporal(newValue);
+        latestAcceptableDate = newValue;
+    }
+
+    /**
+     * Sets the latest date and time collection must be completed.
+     *
+     * @param  newValue  the new latest acceptable data value.
+     *
+     * @deprecated Replaced by {@link #setLatestAcceptableDate(Temporal)}.
+     */
+    @Deprecated(since="1.5")
+    public void setLatestAcceptableDate(final Date newValue) {
+        setLatestAcceptableDate(TemporalDate.toTemporal(newValue));
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequirement.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequirement.java
index 7e90408e3a..357b1ebb35 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequirement.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequirement.java
@@ -65,7 +65,7 @@ import org.opengis.metadata.citation.Responsibility;
  *
  * @author  Cédric Briançon (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.5
+ * @version 2.0
  * @since   0.3
  */
 @XmlType(name = "MI_Requirement_Type", propOrder = {
@@ -151,7 +151,7 @@ public class DefaultRequirement extends ISOMetadata 
implements Requirement {
             recipients     = copyCollection(object.getRecipients(), 
Responsibility.class);
             priority       = object.getPriority();
             requestedDate  = object.getRequestedDate();
-            expiryDate     = TemporalDate.toTemporal(object.getExpiryDate());
+            expiryDate     = object.getExpiryDate();
             satisfiedPlans = copyCollection(object.getSatisfiedPlans(), 
Plan.class);
         }
     }
@@ -310,21 +310,39 @@ public class DefaultRequirement extends ISOMetadata 
implements Requirement {
      * Returns the date and time after which collection is no longer valid.
      *
      * @return date and time after which collection is no longer valid, or 
{@code null}.
+     * @version 2.0
      */
     @Override
     @XmlElement(name = "expiryDate", required = true)
-    public Date getExpiryDate() {
-        return TemporalDate.toDate(expiryDate);
+    public Temporal getExpiryDate() {
+        return expiryDate;
     }
 
     /**
      * Sets the date and time after which collection is no longer valid.
+     * The specified value should be an instance of {@link 
java.time.LocalDate}, {@link java.time.LocalDateTime},
+     * {@link java.time.OffsetDateTime} or {@link java.time.ZonedDateTime}, 
depending whether hours are defined
+     * and how the timezone (if any) is defined. But other types are also 
allowed.
      *
      * @param  newValue  the new expiry date.
+     *
+     * @since 1.5
      */
-    public void setExpiryDate(final Date newValue) {
+    public void setExpiryDate(final Temporal newValue) {
         checkWritePermission(expiryDate);
-        expiryDate = TemporalDate.toTemporal(newValue);
+        expiryDate = newValue;
+    }
+
+    /**
+     * Sets the date and time after which collection is no longer valid.
+     *
+     * @param  newValue  the new expiry date.
+     *
+     * @deprecated Replaced by {@link #setExpiryDate(Temporal)}.
+     */
+    @Deprecated(since="1.5")
+    public void setExpiryDate(final Date newValue) {
+        setExpiryDate(TemporalDate.toTemporal(newValue));
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/package-info.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/package-info.java
index eb390c7a66..a7dd6e7817 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/package-info.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/package-info.java
@@ -101,7 +101,7 @@
     @XmlJavaTypeAdapter(CI_Citation.class),
     @XmlJavaTypeAdapter(CI_Responsibility.class),
     @XmlJavaTypeAdapter(EX_Extent.class),
-    @XmlJavaTypeAdapter(GO_DateTime.class),
+    @XmlJavaTypeAdapter(GO_Temporal.class),
     @XmlJavaTypeAdapter(GO_Real.class),
     @XmlJavaTypeAdapter(GM_Object.class),
     @XmlJavaTypeAdapter(MD_Identifier.class),
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/DefaultCitation.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/DefaultCitation.java
index e1ee3f2c1b..d911b0cba3 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/DefaultCitation.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/DefaultCitation.java
@@ -72,7 +72,7 @@ import org.opengis.metadata.citation.Responsibility;
  * @author  Cédric Briançon (Geomatys)
  * @author  Rémi Maréchal (Geomatys)
  * @author  Cullen Rombach (Image Matters)
- * @version 1.5
+ * @version 2.0
  * @since   0.3
  */
 @TitleProperty(name = "title")
@@ -214,7 +214,7 @@ public class DefaultCitation extends ISOMetadata implements 
Citation {
             alternateTitles         = 
copyCollection(object.getAlternateTitles(), InternationalString.class);
             dates                   = copyCollection(object.getDates(), 
CitationDate.class);
             edition                 = object.getEdition();
-            editionDate             = 
TemporalDate.toTemporal(object.getEditionDate());
+            editionDate             = object.getEditionDate();
             identifiers             = copyCollection(object.getIdentifiers(), 
Identifier.class);
             citedResponsibleParties = 
copyCollection(object.getCitedResponsibleParties(), Responsibility.class);
             presentationForms       = 
copyCollection(object.getPresentationForms(), PresentationForm.class);
@@ -347,21 +347,40 @@ public class DefaultCitation extends ISOMetadata 
implements Citation {
      * Returns the date of the edition.
      *
      * @return the edition date, or {@code null} if none.
+     * @version 2.0
      */
     @Override
     @XmlElement(name = "editionDate")
-    public Date getEditionDate() {
-        return TemporalDate.toDate(editionDate);
+    public Temporal getEditionDate() {
+        return editionDate;
     }
 
     /**
      * Sets the date of the edition.
+     * The specified value should be an instance of {@link 
java.time.LocalDate}, {@link java.time.LocalDateTime},
+     * {@link java.time.OffsetDateTime} or {@link java.time.ZonedDateTime}, 
depending whether hours are defined
+     * and how the timezone (if any) is defined. But other types are also 
allowed.
+     * For example, a citation date may be merely a {@link java.time.Year}.
      *
      * @param  newValue  the new edition date, or {@code null} if none.
+     *
+     * @since 1.5
      */
-    public void setEditionDate(final Date newValue) {
+    public void setEditionDate(final Temporal newValue) {
         checkWritePermission(editionDate);
-        editionDate = TemporalDate.toTemporal(newValue);
+        editionDate = newValue;
+    }
+
+    /**
+     * Sets the date of the edition.
+     *
+     * @param  newValue  the new edition date, or {@code null} if none.
+     *
+     * @deprecated Replaced by {@link #setEditionDate(Temporal)}.
+     */
+    @Deprecated(since="1.5")
+    public void setEditionDate(final Date newValue) {
+        setEditionDate(TemporalDate.toTemporal(newValue));
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/DefaultCitationDate.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/DefaultCitationDate.java
index 42b24c4042..2db4683608 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/DefaultCitationDate.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/DefaultCitationDate.java
@@ -52,7 +52,7 @@ import org.apache.sis.util.privy.TemporalDate;
  */
 @TitleProperty(name = "date")
 @XmlType(name = "CI_Date_Type", propOrder = {
-    "date",
+    "referenceDate",
     "dateType"
 })
 @XmlRootElement(name = "CI_Date")
@@ -152,35 +152,53 @@ public class DefaultCitationDate extends ISOMetadata 
implements CitationDate {
     /**
      * Returns the reference date for the cited resource.
      *
-     * <div class="warning"><b>Upcoming API change — temporal schema</b><br>
-     * The return type of this method may change in a future version.
-     * It may be replaced by {@link Temporal}.</div>
-     *
      * @return reference date for the cited resource, or {@code null}.
+     *
+     * @deprecated Replaced by {@link #getReferenceDate()}.
      */
     @Override
-    @XmlElement(name = "date", required = true)
+    @Deprecated(since="1.5")
     public Date getDate() {
-        return TemporalDate.toDate(date);
+        return TemporalDate.toDate(getReferenceDate());
     }
 
     /**
      * Sets the reference date for the cited resource.
      *
      * @param  newValue  the new date.
+     *
+     * @deprecated Replaced by {@link #setReferenceDate(Temporal)}.
      */
+    @Deprecated(since="1.5")
     public void setDate(final Date newValue) {
-        setDate(TemporalDate.toTemporal(newValue));
+        setReferenceDate(TemporalDate.toTemporal(newValue));
+    }
+
+    /**
+     * Returns the reference date for the cited resource.
+     *
+     * @return reference date for the cited resource, or {@code null}.
+     *
+     * @since 1.5
+     */
+    @Override
+    @XmlElement(name = "date", required = true)
+    public Temporal getReferenceDate() {
+        return date;
     }
 
     /**
      * Sets the reference date for the cited resource.
+     * The specified value should be an instance of {@link 
java.time.LocalDate}, {@link java.time.LocalDateTime},
+     * {@link java.time.OffsetDateTime} or {@link java.time.ZonedDateTime}, 
depending whether hours are defined
+     * and how the timezone (if any) is defined. But other types are also 
allowed.
+     * For example, a citation date may be merely a {@link java.time.Year}.
      *
      * @param  newValue  the new date.
      *
      * @since 1.5
      */
-    public void setDate(final Temporal newValue) {
+    public void setReferenceDate(final Temporal newValue) {
         checkWritePermission(date);
         date = newValue;
     }
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/package-info.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/package-info.java
index 7637116932..fe3285063a 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/package-info.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/citation/package-info.java
@@ -112,7 +112,7 @@
     @XmlJavaTypeAdapter(CI_Series.class),
     @XmlJavaTypeAdapter(CI_Telephone.class),
     @XmlJavaTypeAdapter(EX_Extent.class),
-    @XmlJavaTypeAdapter(GO_DateTime.class),
+    @XmlJavaTypeAdapter(GO_Temporal.class),
     @XmlJavaTypeAdapter(MD_BrowseGraphic.class),
     @XmlJavaTypeAdapter(MD_Identifier.class),
 
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultStandardOrderProcess.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultStandardOrderProcess.java
index 2991ced2ec..985cfdb18e 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultStandardOrderProcess.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultStandardOrderProcess.java
@@ -55,7 +55,7 @@ import org.apache.sis.util.privy.TemporalDate;
  */
 @XmlType(name = "MD_StandardOrderProcess_Type", propOrder = {
     "fees",
-    "plannedAvailableDateTime",
+    "plannedAvailableDate",
     "orderingInstructions",
     "turnaround",
     "orderOptionsType",             // New in ISO 19115-3
@@ -129,7 +129,7 @@ public class DefaultStandardOrderProcess extends 
ISOMetadata implements Standard
         super(object);
         if (object != null) {
             fees                     = object.getFees();
-            plannedAvailableDateTime = 
TemporalDate.toTemporal(object.getPlannedAvailableDateTime());
+            plannedAvailableDateTime = object.getPlannedAvailableDate();
             orderingInstructions     = object.getOrderingInstructions();
             turnaround               = object.getTurnaround();
             orderOptionsType         = object.getOrderOptionsType();
@@ -230,21 +230,53 @@ public class DefaultStandardOrderProcess extends 
ISOMetadata implements Standard
      * Returns the date and time when the dataset will be available.
      *
      * @return date and time when the dataset will be available, or {@code 
null}.
+     *
+     * @deprecated Replaced by {@link #getPlannedAvailableDate()}.
      */
     @Override
-    @XmlElement(name = "plannedAvailableDateTime")
+    @Deprecated(since="1.5")
     public Date getPlannedAvailableDateTime() {
-        return TemporalDate.toDate(plannedAvailableDateTime);
+        return TemporalDate.toDate(getPlannedAvailableDate());
     }
 
     /**
      * Sets the date and time when the dataset will be available.
      *
      * @param  newValue  the new planned available time.
+     *
+     * @deprecated Replaced by {@link #setPlannedAvailableDate(Temporal)}.
      */
+    @Deprecated(since="1.5")
     public void setPlannedAvailableDateTime(final Date newValue) {
+        setPlannedAvailableDate(TemporalDate.toTemporal(newValue));
+    }
+
+    /**
+     * Returns the date and time when the dataset will be available.
+     *
+     * @return date and time when the dataset will be available, or {@code 
null}.
+     *
+     * @since 1.5
+     */
+    @Override
+    @XmlElement(name = "plannedAvailableDateTime")
+    public Temporal getPlannedAvailableDate() {
+        return plannedAvailableDateTime;
+    }
+
+    /**
+     * Sets the date and time when the dataset will be available.
+     * The specified value should be an instance of {@link 
java.time.LocalDate}, {@link java.time.LocalDateTime},
+     * {@link java.time.OffsetDateTime} or {@link java.time.ZonedDateTime}, 
depending whether hours are defined
+     * and how the timezone (if any) is defined. But other types are also 
allowed.
+     *
+     * @param  newValue  the new planned available time.
+     *
+     * @since 1.5
+     */
+    public void setPlannedAvailableDate(final Temporal newValue) {
         checkWritePermission(plannedAvailableDateTime);
-        plannedAvailableDateTime = TemporalDate.toTemporal(newValue);
+        plannedAvailableDateTime = newValue;
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/package-info.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/package-info.java
index 07becb2d25..60b3a9793b 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/package-info.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/package-info.java
@@ -84,7 +84,7 @@
 @XmlJavaTypeAdapters({
     @XmlJavaTypeAdapter(CI_OnlineResource.class),
     @XmlJavaTypeAdapter(CI_Responsibility.class),
-    @XmlJavaTypeAdapter(GO_DateTime.class),
+    @XmlJavaTypeAdapter(GO_Temporal.class),
     @XmlJavaTypeAdapter(GO_Integer.class),
     @XmlJavaTypeAdapter(GO_GenericName.class),
     @XmlJavaTypeAdapter(GO_Real.class),
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultUsage.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultUsage.java
index e0ba370734..cf6f3f105a 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultUsage.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/identification/DefaultUsage.java
@@ -17,17 +17,24 @@
 package org.apache.sis.metadata.iso.identification;
 
 import java.util.Date;
+import java.util.List;
 import java.util.Collection;
 import java.time.temporal.Temporal;
 import jakarta.xml.bind.annotation.XmlType;
 import jakarta.xml.bind.annotation.XmlElement;
 import jakarta.xml.bind.annotation.XmlRootElement;
+import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.identification.Usage;
+import org.opengis.temporal.TemporalPrimitive;
 import org.apache.sis.xml.bind.FilterByVersion;
+import org.apache.sis.xml.bind.gml.TM_Primitive;
+import org.apache.sis.xml.privy.LegacyNamespaces;
 import org.apache.sis.metadata.TitleProperty;
 import org.apache.sis.metadata.iso.ISOMetadata;
+import org.apache.sis.metadata.internal.Dependencies;
+import org.apache.sis.pending.temporal.TemporalUtilities;
 import org.apache.sis.util.iso.Types;
 import org.apache.sis.util.privy.TemporalDate;
 
@@ -68,6 +75,7 @@ import org.opengis.metadata.citation.Responsibility;
 @XmlType(name = "MD_Usage_Type", propOrder = {
     "specificUsage",
     "usageDate",
+    "usageDates",
     "userDeterminedLimitations",
     "userContactInfo",
     "response",                     // New in ISO 19115:2014
@@ -79,7 +87,7 @@ public class DefaultUsage extends ISOMetadata implements 
Usage {
     /**
      * Serial number for compatibility with different versions.
      */
-    private static final long serialVersionUID = -4161209112438016820L;
+    private static final long serialVersionUID = -685588625450110348L;
 
     /**
      * Brief description of the resource and/or resource series usage.
@@ -90,8 +98,8 @@ public class DefaultUsage extends ISOMetadata implements 
Usage {
     /**
      * Date and time of the first use or range of uses of the resource and/or 
resource series.
      */
-    @SuppressWarnings("serial")     // Standard Java implementations are 
serializable.
-    private Temporal usageDate;
+    @SuppressWarnings("serial")
+    private Collection<TemporalPrimitive> usageDates;
 
     /**
      * Applications, determined by the user for which the resource and/or 
resource series
@@ -159,7 +167,7 @@ public class DefaultUsage extends ISOMetadata implements 
Usage {
         super(object);
         if (object != null) {
             specificUsage             = object.getSpecificUsage();
-            usageDate                 = 
TemporalDate.toTemporal(object.getUsageDate());
+            usageDates                = copyCollection(object.getUsageDates(), 
TemporalPrimitive.class);
             userDeterminedLimitations = object.getUserDeterminedLimitations();
             userContactInfo           = 
copyCollection(object.getUserContactInfo(), Responsibility.class);
             responses                 = copyCollection(object.getResponses(), 
InternationalString.class);
@@ -218,21 +226,80 @@ public class DefaultUsage extends ISOMetadata implements 
Usage {
      * Returns the date and time of the first use or range of uses of the 
resource and/or resource series.
      *
      * @return date of the first use of the resource, or {@code null}.
+     *
+     * @deprecated Replaced by {@link #getUsageDates()}.
      */
     @Override
-    @XmlElement(name = "usageDateTime")
+    @Deprecated(since="1.5")
+    @Dependencies("getUsageDates")
+    @XmlElement(name = "usageDateTime", namespace = LegacyNamespaces.GMD)
     public Date getUsageDate() {
-        return TemporalDate.toDate(usageDate);
+        if (FilterByVersion.LEGACY_METADATA.accept()) {
+            @SuppressWarnings("LocalVariableHidesMemberVariable")
+            final Collection<TemporalPrimitive> usageDates = getUsageDates();
+            if (usageDates != null) {
+                for (TemporalPrimitive t : usageDates) {
+                    Date p = TemporalDate.toDate(t.position().orElse(null));
+                    if (p != null) {
+                        return p;
+                    }
+                }
+            }
+        }
+        return null;
     }
 
     /**
      * Sets the date and time of the first use.
      *
      * @param  newValue  the new usage date.
+     *
+     * @deprecated Replaced by {@link #setUsageDates(Collection)}.
      */
+    @Deprecated(since="1.5")
     public void setUsageDate(final Date newValue)  {
-        checkWritePermission(usageDate);
-        usageDate = TemporalDate.toTemporal(newValue);
+        setUsageDates(newValue == null ? List.of() : 
List.of(TemporalUtilities.createInstant(TemporalDate.toTemporal(newValue))));
+    }
+
+    /**
+     * Returns the date and time of the first use or range of uses of the 
resource and/or resource series.
+     *
+     * @return date of the first use of the resource.
+     *
+     * @since 1.5
+     */
+    @Override
+    @XmlElement(name = "usageDateTime")
+    @XmlJavaTypeAdapter(TM_Primitive.Since2014.class)
+    public Collection<TemporalPrimitive> getUsageDates() {
+        return usageDates = nonNullCollection(usageDates, 
TemporalPrimitive.class);
+    }
+
+    /**
+     * Sets the date and time of the first use or range of uses of the 
resource and/or resource series.
+     *
+     * @param  newValues  date of the first use of the resource.
+     *
+     * @since 1.5
+     */
+    public void setUsageDates(final Collection<TemporalPrimitive> newValues) {
+        usageDates = writeCollection(usageDates, newValues, 
TemporalPrimitive.class);
+    }
+
+    /**
+     * Adds a period for the range of uses of the resource and/or resource 
series.
+     * This is a convenience method for adding a temporal period.
+     *
+     * @param  beginning  the begin instant (inclusive), or {@code null}.
+     * @param  ending     the end instant (inclusive), or {@code null}.
+     *
+     * @since 1.5
+     */
+    public void addUsageDates(final Temporal beginning, final Temporal ending) 
{
+        TemporalPrimitive period = TemporalUtilities.createPeriod(beginning, 
ending);
+        if (period != null) {
+            getUsageDates().add(period);
+        }
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/AbstractResult.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/AbstractResult.java
index 3380c3d6f0..e758c03a49 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/AbstractResult.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/AbstractResult.java
@@ -174,9 +174,9 @@ public class AbstractResult extends ISOMetadata implements 
Result {
 
     /**
      * Returns the date when the result was generated.
-     * This is typically a {@link java.time.LocalDate}, {@link 
java.time.LocalDateTime}
-     * or {@link java.time.ZonedDateTime} depending on whether the hour of the 
day and
-     * the time zone are provided.
+     * The specified value should be an instance of {@link 
java.time.LocalDate}, {@link java.time.LocalDateTime},
+     * {@link java.time.OffsetDateTime} or {@link java.time.ZonedDateTime}, 
depending whether hours are defined
+     * and how the timezone (if any) is defined. But other types are also 
allowed.
      *
      * @return date of the result, or {@code null} if none.
      *
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/pending/temporal/TemporalUtilities.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/pending/temporal/TemporalUtilities.java
index 1e579a781a..a8800060f8 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/pending/temporal/TemporalUtilities.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/pending/temporal/TemporalUtilities.java
@@ -51,14 +51,14 @@ public final class TemporalUtilities {
     /**
      * Creates a period for the given begin and end instant.
      *
-     * @param  begin  the begin instant (inclusive), or {@code null}.
-     * @param  end    the end instant (inclusive), or {@code null}.
+     * @param  beginning  the begin instant (inclusive), or {@code null}.
+     * @param  ending     the end instant (inclusive), or {@code null}.
      * @return the period, or {@code null} if both arguments are null.
      *
      * @todo Needs to avoid assuming UTC timezone.
      */
-    public static TemporalPrimitive createPeriod(final Temporal begin, final 
Temporal end) {
-        return (begin == null && end == null) ? null : new 
DefaultPeriod(begin, end);
+    public static TemporalPrimitive createPeriod(final Temporal beginning, 
final Temporal ending) {
+        return (beginning == null && ending == null) ? null : new 
DefaultPeriod(beginning, ending);
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/PropertyAccessorTest.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/PropertyAccessorTest.java
index 1d0cf3aa69..e8e536cefc 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/PropertyAccessorTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/PropertyAccessorTest.java
@@ -22,7 +22,7 @@ import java.util.List;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Locale;
-import java.util.Date;
+import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAmount;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.extent.Extent;
@@ -181,7 +181,7 @@ public final class PropertyAccessorTest extends TestCase {
             Citation.class, "getAlternateTitles",         "alternateTitles",   
      "alternateTitle",        "Alternate titles",           
InternationalString[].class,
             Citation.class, "getDates",                   "dates",             
      "date",                  "Dates",                      
CitationDate[].class,
             Citation.class, "getEdition",                 "edition",           
      "edition",               "Edition",                    
InternationalString.class,
-            Citation.class, "getEditionDate",             "editionDate",       
      "editionDate",           "Edition date",               Date.class,
+            Citation.class, "getEditionDate",             "editionDate",       
      "editionDate",           "Edition date",               Temporal.class,
             Citation.class, "getIdentifiers",             "identifiers",       
      "identifier",            "Identifiers",                Identifier[].class,
             Citation.class, "getCitedResponsibleParties", 
"citedResponsibleParties", "citedResponsibleParty", "Cited responsible 
parties",  Responsibility[].class,
             Citation.class, "getPresentationForms",       "presentationForms", 
      "presentationForm",      "Presentation forms",         
PresentationForm[].class,
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TreeNodeChildrenTest.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TreeNodeChildrenTest.java
index c776b19885..9a6aaa6898 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TreeNodeChildrenTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TreeNodeChildrenTest.java
@@ -16,11 +16,11 @@
  */
 package org.apache.sis.metadata;
 
-import java.util.Date;
 import java.util.Random;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ArrayList;
+import java.time.LocalDate;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.citation.DateType;
 import org.opengis.metadata.citation.PresentationForm;
@@ -137,7 +137,7 @@ public final class TreeNodeChildrenTest extends TestCase {
      */
     static DefaultCitation metadataSimplifiable() {
         final DefaultCitation citation = new DefaultCitation();
-        final DefaultCitationDate date = new 
DefaultCitationDate(TestUtilities.date("2012-01-01 00:00:00"), 
DateType.CREATION);
+        final DefaultCitationDate date = new 
DefaultCitationDate(LocalDate.of(2012, 1, 1), DateType.CREATION);
         assertTrue(citation.getDates().add(date));
         return citation;
     }
@@ -230,7 +230,7 @@ public final class TreeNodeChildrenTest extends TestCase {
          * We need to perform the tests on the "Date" node, not on the 
"DefaultCitation" node.
          */
         final TreeTable.Node node = 
TestUtilities.getSingleton(create(citation, ValueExistencePolicy.COMPACT));
-        assertEquals(1325376000000L, ((Date) 
node.getValue(TableColumn.VALUE)).getTime());
+        assertEquals(15340, ((LocalDate) 
node.getValue(TableColumn.VALUE)).toEpochDay());
         final TreeNodeChildren children = (TreeNodeChildren) 
node.getChildren();
         final String[] expected = {
             // The "Date" node should be omitted because merged with the 
parent "Date" node.
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TypeMapTest.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TypeMapTest.java
index 9410f74813..c4dc2e5217 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TypeMapTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/TypeMapTest.java
@@ -18,7 +18,7 @@ package org.apache.sis.metadata;
 
 import java.util.Map;
 import java.util.Collection;
-import java.util.Date;
+import java.time.temporal.Temporal;
 import static java.util.AbstractMap.SimpleEntry;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
@@ -72,7 +72,7 @@ public final class TypeMapTest extends TestCase {
             new SimpleEntry<>("alternateTitle",        
InternationalString.class),
             new SimpleEntry<>("date",                  CitationDate.class),
             new SimpleEntry<>("edition",               
InternationalString.class),
-            new SimpleEntry<>("editionDate",           Date.class),
+            new SimpleEntry<>("editionDate",           Temporal.class),
             new SimpleEntry<>("identifier",            Identifier.class),
             new SimpleEntry<>("citedResponsibleParty", Responsibility.class),
             new SimpleEntry<>("presentationForm",      PresentationForm.class),
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/citation/DefaultCitationDateTest.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/citation/DefaultCitationDateTest.java
index 4788d6caf9..5545fd5921 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/citation/DefaultCitationDateTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/citation/DefaultCitationDateTest.java
@@ -16,11 +16,14 @@
  */
 package org.apache.sis.metadata.iso.citation;
 
-import java.util.Date;
 import org.opengis.metadata.citation.DateType;
 import org.opengis.metadata.citation.CitationDate;
 import org.apache.sis.util.ComparisonMode;
 
+// Specific to the geoapi-4.0 branch:
+import java.time.Instant;
+import java.time.temporal.Temporal;
+
 // Test dependencies
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
@@ -45,11 +48,11 @@ public final class DefaultCitationDateTest extends TestCase 
{
     @Test
     public void testCopyConstructor() {
         final CitationDate original = new CitationDate() {
-            @Override public Date     getDate()     {return new 
Date(1305716658508L);}
-            @Override public DateType getDateType() {return DateType.CREATION;}
+            @Override public Temporal getReferenceDate() {return 
Instant.ofEpochMilli(1305716658508L);}
+            @Override public DateType getDateType()      {return 
DateType.CREATION;}
         };
         final DefaultCitationDate copy = new DefaultCitationDate(original);
-        assertEquals(new Date(1305716658508L), copy.getDate());
+        assertEquals(Instant.ofEpochMilli(1305716658508L), 
copy.getReferenceDate());
         assertEquals(DateType.CREATION, copy.getDateType());
         assertTrue (copy.equals(original, ComparisonMode.BY_CONTRACT));
         assertFalse(copy.equals(original, ComparisonMode.STRICT)); // 
Opportunist test.
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
index 667c0ded61..d31ab8df44 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
@@ -23,6 +23,8 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.Locale;
 import java.io.InputStream;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
@@ -48,7 +50,6 @@ 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.metadata.xml.TestUsingFile;
-import org.apache.sis.test.TestUtilities;
 import static org.apache.sis.test.TestUtilities.getSingleton;
 import static org.apache.sis.metadata.Assertions.assertTitleEquals;
 
@@ -251,7 +252,7 @@ public final class DefaultCitationTest extends 
TestUsingFile {
                 new DefaultResponsibility(Role.ORIGINATOR, null, new 
DefaultIndividual("Maid Marian", null, contact)),
                 new DefaultResponsibility(Role.FUNDER,     null, new 
DefaultIndividual("Robin Hood",  null, contact))
         ));
-        c.getDates().add(new 
DefaultCitationDate(TestUtilities.date("2015-10-17 00:00:00"), 
DateType.ADOPTED));
+        c.getDates().add(new DefaultCitationDate(OffsetDateTime.of(2015, 10, 
17, 2, 0, 0, 0, ZoneOffset.ofHours(2)), DateType.ADOPTED));
         c.getPresentationForms().add(PresentationForm.PHYSICAL_OBJECT);
         /*
          * Check that XML file built by the marshaller is the same as the 
example file.
@@ -300,7 +301,7 @@ public final class DefaultCitationTest extends 
TestUsingFile {
         assertTitleEquals("Fight against poverty", c, "citation");
 
         final CitationDate date = getSingleton(c.getDates());
-        assertEquals(date.getDate(), TestUtilities.date("2015-10-17 
00:00:00"));
+        assertEquals(date.getReferenceDate(), OffsetDateTime.of(2015, 10, 17, 
2, 0, 0, 0, ZoneOffset.ofHours(2)));
         assertEquals(DateType.ADOPTED, date.getDateType());
         assertEquals(PresentationForm.PHYSICAL_OBJECT, 
getSingleton(c.getPresentationForms()));
 
@@ -308,7 +309,7 @@ public final class DefaultCitationTest extends 
TestUsingFile {
         final Contact contact = assertResponsibilityEquals(Role.ORIGINATOR, 
"Maid Marian", it.next());
         assertEquals("Send carrier pigeon.", 
String.valueOf(contact.getContactInstructions()));
 
-        final OnlineResource resource = 
TestUtilities.getSingleton(contact.getOnlineResources());
+        final OnlineResource resource = 
getSingleton(contact.getOnlineResources());
         assertEquals("IP over Avian Carriers", 
String.valueOf(resource.getName()));
         assertEquals("High delay, low throughput, and low altitude service.", 
String.valueOf(resource.getDescription()));
         assertEquals("https://tools.ietf.org/html/rfc1149";, 
String.valueOf(resource.getLinkage()));
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 fc751b518f..5278d26984 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
@@ -20,6 +20,7 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
 import java.util.Locale;
+import java.time.LocalDate;
 import java.nio.charset.StandardCharsets;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.citation.DateType;
@@ -66,7 +67,7 @@ public final class DefaultDataIdentificationTest extends 
TestCase {
          *       └─Code……………………………………………………………………… 
NCEP/SST/Global_5x2p5deg/SST_Global_5x2p5deg_20050922_0000.nc
          */
         final var citation = new DefaultCitation("Sea Surface Temperature 
Analysis Model");
-        citation.setDates(Set.of(new 
DefaultCitationDate(TestUtilities.date("2005-09-22 00:00:00"), 
DateType.CREATION)));
+        citation.setDates(Set.of(new DefaultCitationDate(LocalDate.of(2005, 9, 
22), DateType.CREATION)));
         citation.setIdentifiers(Set.of(new 
DefaultIdentifier("SST_Global.nc")));
         /*
          * Descriptive keywords
@@ -128,7 +129,7 @@ public final class DefaultDataIdentificationTest extends 
TestCase {
         assertMultilinesEquals(
                 "Data identification\n" +
                 "  ├─Citation………………………………………………………… Sea Surface Temperature 
Analysis Model\n" +
-                "  │   ├─Date………………………………………………………… 2005-09-22 00:00:00\n" +
+                "  │   ├─Date………………………………………………………… 2005 Sep 22\n" +
                 "  │   │   └─Date type………………………………… Creation\n" +
                 "  │   └─Identifier………………………………………… SST_Global.nc\n" +
                 "  ├─Abstract………………………………………………………… Global 5.0 x 2.5 degree 
model data\n" +
diff --git 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/test/AnnotationConsistencyCheck.java
 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/test/AnnotationConsistencyCheck.java
index 838440acd1..35a356c619 100644
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/test/AnnotationConsistencyCheck.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/test/AnnotationConsistencyCheck.java
@@ -581,6 +581,13 @@ public abstract class AnnotationConsistencyCheck extends 
TestCaseWithLogs {
             case "getDerivedElements": {
                 return 
org.opengis.metadata.quality.Metaquality.class.isAssignableFrom(method.getDeclaringClass());
             }
+            /*
+             * Property which exists in a deprecated and a non-deprecated 
version,
+             * with the same name but different namespace.
+             */
+            case "usageDateTime": {
+                return method.isAnnotationPresent(Deprecated.class);
+            }
             /*
              * - "resultContent" is a property in the ISO 10157 model but not 
yet in the XML schema.
              * - "resultFormat" and "resultFile" differ in XML schema compared 
to abstract model (different obligation).
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/AbstractDatum.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/AbstractDatum.java
index eaea0521a1..917dcaaebc 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/AbstractDatum.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/AbstractDatum.java
@@ -35,6 +35,7 @@ import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.iso.Types;
+import org.apache.sis.util.privy.TemporalDate;
 import org.apache.sis.metadata.privy.Identifiers;
 import org.apache.sis.metadata.privy.NameToIdentifier;
 import org.apache.sis.metadata.privy.ImplementationHelper;
@@ -44,9 +45,6 @@ import org.apache.sis.io.wkt.Formatter;
 import static org.apache.sis.util.Utilities.deepEquals;
 import static org.apache.sis.util.collection.Containers.property;
 
-// Specific to the main and geoapi-4.0 branches:
-import org.apache.sis.util.privy.TemporalDate;
-
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
 import org.opengis.metadata.Identifier;
 
diff --git 
a/endorsed/src/org.apache.sis.storage.earthobservation/test/org/apache/sis/storage/landsat/MetadataReaderTest.java
 
b/endorsed/src/org.apache.sis.storage.earthobservation/test/org/apache/sis/storage/landsat/MetadataReaderTest.java
index ee9a6ad159..954c104830 100644
--- 
a/endorsed/src/org.apache.sis.storage.earthobservation/test/org/apache/sis/storage/landsat/MetadataReaderTest.java
+++ 
b/endorsed/src/org.apache.sis.storage.earthobservation/test/org/apache/sis/storage/landsat/MetadataReaderTest.java
@@ -27,6 +27,8 @@ import org.apache.sis.test.TestCase;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.acquisition.Context;
 import org.opengis.metadata.acquisition.OperationType;
@@ -44,7 +46,6 @@ import org.apache.sis.storage.AbstractResource;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.event.StoreListeners;
 import org.opengis.test.dataset.ContentVerifier;
-import static org.apache.sis.test.TestUtilities.date;
 
 
 /**
@@ -100,10 +101,10 @@ public final class MetadataReaderTest extends TestCase {
             "defaultLocale+otherLocale[0]",                                    
                      "en",
             "metadataIdentifier.code",                                         
                      "LandsatTest",
             "metadataScope[0].resourceScope",                                  
                      ScopeCode.COVERAGE,
-            "dateInfo[0].date",                                                
                      date("2016-06-27 16:48:12"),
+            "dateInfo[0].date",                                                
                      OffsetDateTime.of(2016, 6, 27, 16, 48, 12, 0, 
ZoneOffset.UTC),
             "dateInfo[0].dateType",                                            
                      DateType.CREATION,
             "identificationInfo[0].topicCategory[0]",                          
                      TopicCategory.GEOSCIENTIFIC_INFORMATION,
-            "identificationInfo[0].citation.date[0].date",                     
                      date("2016-06-27 16:48:12"),
+            "identificationInfo[0].citation.date[0].date",                     
                      OffsetDateTime.of(2016, 6, 27, 16, 48, 12, 0, 
ZoneOffset.UTC),
             "identificationInfo[0].citation.date[0].dateType",                 
                      DateType.CREATION,
             "identificationInfo[0].citation.title",                            
                      "LandsatTest",
             "identificationInfo[0].credit[0]",                                 
                      "Derived from U.S. Geological Survey data",
@@ -123,7 +124,7 @@ public final class MetadataReaderTest extends TestCase {
             
"acquisitionInformation[0].platform[0].instrument[0].identifier.code", "Pseudo 
TIRS",
             
"acquisitionInformation[0].acquisitionRequirement[0].identifier.code", 
"Software unit tests",
             
"acquisitionInformation[0].operation[0].significantEvent[0].context",  
Context.ACQUISITION,
-            "acquisitionInformation[0].operation[0].significantEvent[0].time", 
    date("2016-06-26 03:02:01.090"),
+            "acquisitionInformation[0].operation[0].significantEvent[0].time", 
    OffsetDateTime.of(2016, 6, 26, 3, 2, 1, 90_000_000, ZoneOffset.UTC),
             "acquisitionInformation[0].operation[0].status",                   
    Progress.COMPLETED,
             "acquisitionInformation[0].operation[0].type",                     
    OperationType.REAL,
 
diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/MetadataReaderTest.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/MetadataReaderTest.java
index 001d70f590..3550322273 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/MetadataReaderTest.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/MetadataReaderTest.java
@@ -17,6 +17,9 @@
 package org.apache.sis.storage.netcdf;
 
 import java.io.IOException;
+import java.time.ZoneOffset;
+import java.time.LocalDateTime;
+import java.time.temporal.Temporal;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.citation.Role;
 import org.opengis.metadata.citation.DateType;
@@ -36,7 +39,6 @@ import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import org.apache.sis.storage.netcdf.base.TestCase;
 import org.apache.sis.storage.netcdf.classic.ChannelDecoderTest;
-import static org.apache.sis.test.TestUtilities.date;
 
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
 import org.opengis.test.dataset.ContentVerifier;
@@ -77,7 +79,7 @@ public final class MetadataReaderTest extends TestCase {
         final Decoder input = 
ChannelDecoderTest.createChannelDecoder(TestData.NETCDF_2D_GEOGRAPHIC);
         final Metadata metadata = new MetadataReader(input).read();
         input.close(new DataStoreMock("lock"));
-        compareToExpected(metadata).assertMetadataEquals();
+        compareToExpected(metadata, false).assertMetadataEquals();
     }
 
     /**
@@ -92,16 +94,30 @@ public final class MetadataReaderTest extends TestCase {
         final Decoder input = createDecoder(TestData.NETCDF_2D_GEOGRAPHIC);
         final Metadata metadata = new MetadataReader(input).read();
         input.close(new DataStoreMock("lock"));
-        final ContentVerifier verifier = compareToExpected(metadata);
+        final ContentVerifier verifier = compareToExpected(metadata, true);
         
verifier.addExpectedValue("identificationInfo[0].resourceFormat[0].formatSpecificationCitation.alternateTitle[1]",
 "NetCDF-3/CDM");
         verifier.assertMetadataEquals();
     }
 
+    /**
+     * Converts the given object to the actual type stored in the metadata.
+     *
+     * @param  expected  the expected date to convert.
+     * @param  ucar      whether the UCAR wrapper is used.
+     * @return the given date converted to the expected type.
+     */
+    private static Temporal actual(final LocalDateTime expected, final boolean 
ucar) {
+        return ucar ? expected.toInstant(ZoneOffset.UTC) : expected;
+    }
+
     /**
      * Creates comparator for the string representation of the given metadata 
object with the expected one.
      * The given metadata shall have been created from the {@link 
TestData#NETCDF_2D_GEOGRAPHIC} dataset.
+     *
+     * @param  actual    the metadata which have been read.
+     * @param  ucar      whether the UCAR wrapper is used.
      */
-    static ContentVerifier compareToExpected(final Metadata actual) {
+    static ContentVerifier compareToExpected(final Metadata actual, final 
boolean ucar) {
         final ContentVerifier verifier = new ContentVerifier();
         verifier.addPropertyToIgnore(Metadata.class, "metadataStandard");
         verifier.addPropertyToIgnore(Metadata.class, "referenceSystemInfo");
@@ -115,7 +131,7 @@ public final class MetadataReaderTest extends TestCase {
             
"identificationInfo[0].resourceFormat[0].formatSpecificationCitation.citedResponsibleParty[0].role",
 Role.PRINCIPAL_INVESTIGATOR,
 
             // Read from the file
-            "dateInfo[0].date",                                                
        date("2018-05-15 13:01:00"),
+            "dateInfo[0].date",                                                
        actual(LocalDateTime.of(2018, 5, 15, 13, 1), ucar),
             "dateInfo[0].dateType",                                            
        DateType.REVISION,
             "metadataScope[0].resourceScope",                                  
        ScopeCode.DATASET,
             "identificationInfo[0].abstract",                                  
        "Global, two-dimensional model data",
@@ -129,8 +145,8 @@ public final class MetadataReaderTest extends TestCase {
             "identificationInfo[0].pointOfContact[0].party[0].name",           
        "NOAA/NWS/NCEP",
             "identificationInfo[0].citation.citedResponsibleParty[0].role",    
        Role.ORIGINATOR,
             
"identificationInfo[0].citation.citedResponsibleParty[0].party[0].name",   
"NOAA/NWS/NCEP",
-            "identificationInfo[0].citation.date[0].date",                     
        date("2005-09-22 00:00:00"),
-            "identificationInfo[0].citation.date[1].date",                     
        date("2018-05-15 13:00:00"),
+            "identificationInfo[0].citation.date[0].date",                     
        actual(LocalDateTime.of(2005, 9, 22,  0, 0), ucar),
+            "identificationInfo[0].citation.date[1].date",                     
        actual(LocalDateTime.of(2018, 5, 15, 13, 0), ucar),
             "identificationInfo[0].citation.date[0].dateType",                 
        DateType.CREATION,
             "identificationInfo[0].citation.date[1].dateType",                 
        DateType.REVISION,
             "identificationInfo[0].citation.identifier[0].code",               
        "NCEP/SST/Global_5x2p5deg/SST_Global_5x2p5deg_20050922_0000.nc",
diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/NetcdfStoreTest.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/NetcdfStoreTest.java
index 540ec9a3a9..a2ea937da1 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/NetcdfStoreTest.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/NetcdfStoreTest.java
@@ -66,7 +66,7 @@ public final class NetcdfStoreTest extends TestCaseWithLogs {
             metadata = store.getMetadata();
             assertSame(metadata, store.getMetadata(), "Should be cached.");
         }
-        MetadataReaderTest.compareToExpected(metadata).assertMetadataEquals();
+        MetadataReaderTest.compareToExpected(metadata, 
false).assertMetadataEquals();
         loggings.skipNextLogIfContains("EPSG:4019");        // Deprecated EPSG 
code.
         loggings.assertNoUnexpectedLog();
     }
diff --git 
a/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/Copyright.java
 
b/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/Copyright.java
index 6a9ba51b4d..88bc82ca4e 100644
--- 
a/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/Copyright.java
+++ 
b/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/Copyright.java
@@ -20,9 +20,11 @@ import java.net.URI;
 import java.util.List;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Date;
 import java.util.Locale;
 import java.util.Objects;
+import java.time.Year;
+import java.time.temporal.Temporal;
+import java.time.temporal.ChronoField;
 import jakarta.xml.bind.annotation.XmlAttribute;
 import jakarta.xml.bind.annotation.XmlElement;
 import org.opengis.metadata.Identifier;
@@ -111,9 +113,9 @@ resp:   for (final Responsibility r : 
c.getResponsibleParties()) {
         }
         for (final Citation ci : c.getReferences()) {
             for (final CitationDate d : ci.getDates()) {
-                final Date date = d.getDate();
+                final Temporal date = d.getReferenceDate();
                 if (date != null) {
-                    year = date.getYear() + 1900;
+                    year = date.get(ChronoField.YEAR);
                     break;
                 }
             }
@@ -299,9 +301,9 @@ resp:   for (final Responsibility r : 
c.getResponsibleParties()) {
      * @return reference date for the cited resource.
      */
     @Override
-    public Date getDate() {
+    public Temporal getReferenceDate() {
         if (year != null) {
-            return new Date(year - 1900, 0, 1);
+            return Year.of(year);
         }
         return null;
     }
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/MetadataBuilder.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/MetadataBuilder.java
index 7843dce4f4..56d5255a92 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/MetadataBuilder.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/MetadataBuilder.java
@@ -2684,7 +2684,7 @@ public class MetadataBuilder {
         if (time != null) {
             final var event = new DefaultEvent();
             event.setContext(Context.ACQUISITION);
-            event.setTime(time);
+            event.setDateOfOccurrence(time);
             final var op = new DefaultOperation();
             op.setSignificantEvents(Collections.singleton(event));
             op.setType(OperationType.REAL);
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/io/CompoundFormat.java 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/io/CompoundFormat.java
index 5d912fa649..e6f35ce5fa 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/io/CompoundFormat.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/io/CompoundFormat.java
@@ -30,6 +30,16 @@ import java.text.FieldPosition;
 import java.text.ParsePosition;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.LocalTime;
+import java.time.OffsetTime;
+import java.time.OffsetDateTime;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
+import java.time.temporal.TemporalAccessor;
 import javax.measure.Quantity;
 import javax.measure.Unit;
 import org.opengis.referencing.IdentifiedObject;
@@ -95,7 +105,7 @@ import static org.apache.sis.util.privy.Constants.UTC;
  * in case of error.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.5
  *
  * @param <T>  the base type of objects parsed and formatted by this class.
  *
@@ -452,6 +462,7 @@ public abstract class CompoundFormat<T> extends Format 
implements Localized {
      *   <tr><td>{@link DirectPosition}</td>  <td>{@link 
org.apache.sis.geometry.CoordinateFormat}</td></tr>
      *   <tr><td>{@link Angle}</td>           <td>{@link AngleFormat}</td></tr>
      *   <tr><td>{@link Date}</td>            <td>{@link DateFormat}</td></tr>
+     *   <tr><td>{@link TemporalAccessor}</td><td>{@link 
DateTimeFormatter}</td></tr>
      *   <tr><td>{@link Number}</td>          <td>{@link 
NumberFormat}</td></tr>
      *   <tr><td>{@link Unit}</td>            <td>{@link UnitFormat}</td></tr>
      *   <tr><td>{@link Quantity}</td>        <td>{@link 
QuantityFormat}</td></tr>
@@ -473,7 +484,7 @@ public abstract class CompoundFormat<T> extends Format 
implements Localized {
      */
     protected Format createFormat(final Class<?> valueType) {
         /*
-         * The first case below is an apparent exception to the 'expected == 
type' rule
+         * The first case below is an apparent exception to the `expected == 
type` rule
          * documented in this method javadoc. But actually it is not, since 
the call to
          * DefaultFormat.getInstance(…) will indirectly perform this kind of 
comparison.
          */
@@ -487,12 +498,26 @@ public abstract class CompoundFormat<T> extends Format 
implements Localized {
             } else if (Numbers.isInteger(valueType)) {
                 return NumberFormat.getIntegerInstance(locale);
             }
+        } else if (TemporalAccessor.class.isAssignableFrom(valueType)) {
+            final DateTimeFormatter format;
+            if (valueType == ChronoLocalDateTime.class || valueType == 
ChronoZonedDateTime.class || valueType == OffsetDateTime.class) {
+                format = 
DateTimeFormatter.ofLocalizedDateTime(getTemporalStyle(true), 
getTemporalStyle(false));
+            } else if (valueType == ChronoLocalDate.class) {
+                format = 
DateTimeFormatter.ofLocalizedDate(getTemporalStyle(true));
+            } else if (valueType == LocalTime.class || valueType == 
OffsetTime.class) {
+                format = 
DateTimeFormatter.ofLocalizedTime(getTemporalStyle(false));
+            } else if (valueType == Instant.class) {
+                format = DateTimeFormatter.ISO_INSTANT;
+            } else {
+                return null;
+            }
+            return format.withLocale(locale).toFormat();
         } else if (valueType == Date.class) {
             final DateFormat format;
-            if (!Locale.ROOT.equals(locale)) {
-                format = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, 
DateFormat.DEFAULT, locale);
-            } else {
+            if (Locale.ROOT.equals(locale)) {
                 format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", 
Locale.ROOT);
+            } else {
+                format = DateFormat.getDateTimeInstance(getLegacyStyle(true), 
getLegacyStyle(false), locale);
             }
             format.setTimeZone(getTimeZone());
             return format;
@@ -517,6 +542,35 @@ public abstract class CompoundFormat<T> extends Format 
implements Localized {
         return null;
     }
 
+    /**
+     * Returns the style to use for formatting dates or times.
+     * This is invoked by the default implementation of {@link 
#createFormat(Class)} when
+     * the formatter to create is a {@link DateFormat} or a {@link 
DateTimeFormatter}.
+     *
+     * @param  dates  {@code true} for the date style, or {@code false} for 
the time (hours) style.
+     * @return the date or time style to use.
+     * @since 1.5
+     */
+    protected FormatStyle getTemporalStyle(final boolean dates) {
+        return FormatStyle.MEDIUM;
+    }
+
+    /**
+     * Returns the style to use for formatting dates or times using legacy 
formatter.
+     *
+     * @param  dates  {@code true} for the date style, or {@code false} for 
the time (hours) style.
+     * @return the date or time style to use.
+     */
+    private int getLegacyStyle(final boolean dates) {
+        switch (getTemporalStyle(dates)) {
+            case FULL:   return DateFormat.FULL;
+            case LONG:   return DateFormat.LONG;
+            case MEDIUM: return DateFormat.MEDIUM;
+            case SHORT:  return DateFormat.SHORT;
+            default:     return DateFormat.DEFAULT;
+        }
+    }
+
     /**
      * Returns a clone of this format.
      *
@@ -539,7 +593,7 @@ public abstract class CompoundFormat<T> extends Format 
implements Localized {
      * Do not override equals(Object) and hashCode(). They are unlikely to be 
needed since we
      * do not expect CompoundFormats to be used as keys in HashMap, especially 
since they are
      * mutable. Furthermore, it is difficult to check for equality since the 
values in the
-     * 'formats' map are created only when needed and we don't know how 
subclasses will
+     * `formats` map are created only when needed and we don't know how 
subclasses will
      * configure them.
      */
 }
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/collection/TreeTableFormat.java
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/collection/TreeTableFormat.java
index 4793af0fc1..9907713a04 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/collection/TreeTableFormat.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/collection/TreeTableFormat.java
@@ -25,12 +25,12 @@ import java.util.Locale;
 import java.util.TimeZone;
 import java.util.ConcurrentModificationException;
 import java.util.function.Predicate;
+import java.util.regex.Matcher;
 import java.io.IOException;
 import java.text.Format;
 import java.text.DecimalFormat;
 import java.text.ParsePosition;
 import java.text.ParseException;
-import java.util.regex.Matcher;
 import org.apache.sis.io.TableAppender;
 import org.apache.sis.io.TabularFormat;
 import org.apache.sis.measure.UnitFormat;
@@ -575,7 +575,9 @@ public class TreeTableFormat extends 
TabularFormat<TreeTable> {
      * @see #clearTreeSymbols()
      */
     private void createTreeSymbols() {
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
         final int indentation = this.indentation;
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
         final int verticalLinePosition = this.verticalLinePosition;
         final char[] buffer = new char[indentation];
         for (int k=0; k<4; k++) {
@@ -679,6 +681,8 @@ public class TreeTableFormat extends 
TabularFormat<TreeTable> {
             this.values  = new Object[columns.length];
             this.isLast  = new boolean[8];
             this.recursivityGuard = recursivityGuard;
+
+            @SuppressWarnings("LocalVariableHidesMemberVariable")   // To be 
stored in the field if successful.
             Predicate<TreeTable.Node> filter = nodeFilter;
             if (tree instanceof TreeFormatCustomization) {
                 final TreeFormatCustomization custom = 
(TreeFormatCustomization) tree;
@@ -686,7 +690,6 @@ public class TreeTableFormat extends 
TabularFormat<TreeTable> {
                 if (more != null) {
                     filter = (filter != null) ? more.and(filter) : more;
                 }
-            } else {
             }
             this.filter = filter;
             setTabulationExpanded(true);
diff --git a/geoapi/snapshot b/geoapi/snapshot
index dd12a26da8..df67b0319b 160000
--- a/geoapi/snapshot
+++ b/geoapi/snapshot
@@ -1 +1 @@
-Subproject commit dd12a26da8121f0af6d324e33195912f21e16969
+Subproject commit df67b0319be5ed161459bfa804ff3e34f366ce3d

Reply via email to