Merge branch 'geoapi-3.1'.
This is mostly about changing the type of `TemporalDatum.origin` to `java.time`, at least internally.
diff --git a/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/AboutCommand.java b/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/AboutCommand.java
index ec5f061..3744340 100644
--- a/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/AboutCommand.java
+++ b/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/AboutCommand.java
@@ -36,7 +36,7 @@
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.collection.TreeTable;
import org.apache.sis.util.collection.TableColumn;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
import org.apache.sis.util.privy.X364;
import org.apache.sis.system.Loggers;
import org.apache.sis.system.Supervisor;
@@ -139,7 +139,7 @@
* Logs a message telling how long it took to receive the reply.
* Sometimes the delay gives a hint about the server charge.
*/
- double delay = (System.nanoTime() - time) / (double) StandardDateFormat.NANOS_PER_SECOND; // In seconds.
+ double delay = (System.nanoTime() - time) / (double) Constants.NANOS_PER_SECOND; // In seconds.
if (delay >= 0.1) {
final double scale = (delay >= 10) ? 1 : (delay >= 1) ? 10 : 100;
delay = Math.rint(delay * scale) / scale;
diff --git a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/feature/FeatureMemoryBenchmark.java b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/feature/FeatureMemoryBenchmark.java
index eb1cefe..f8256c1 100644
--- a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/feature/FeatureMemoryBenchmark.java
+++ b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/feature/FeatureMemoryBenchmark.java
@@ -21,7 +21,7 @@
import java.util.List;
import java.util.Map;
import java.util.Random;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
// Test dependencies
import org.apache.sis.test.Benchmark;
@@ -182,7 +182,7 @@
long time = System.nanoTime();
b.run();
time = System.nanoTime() - time;
- System.console().printf("Ellapsed time: %f%n", time / (float) StandardDateFormat.NANOS_PER_SECOND);
+ System.console().printf("Ellapsed time: %f%n", time / (float) Constants.NANOS_PER_SECOND);
return;
}
}
diff --git a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/filter/PeriodLiteral.java b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/filter/PeriodLiteral.java
index 3c5b646..faa3eb8 100644
--- a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/filter/PeriodLiteral.java
+++ b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/filter/PeriodLiteral.java
@@ -16,13 +16,9 @@
*/
package org.apache.sis.filter;
-import java.util.Date;
import java.time.Instant;
import java.io.Serializable;
-// Test dependencies
-import org.apache.sis.test.TestUtilities;
-
// Specific to the main branch:
import org.apache.sis.feature.AbstractFeature;
import org.apache.sis.pending.geoapi.filter.Literal;
@@ -86,7 +82,7 @@
*/
@Override
public String toString() {
- return "Period[" + TestUtilities.format(new Date(begin)) +
- " ... " + TestUtilities.format(new Date(end)) + ']';
+ return "Period[" + Instant.ofEpochMilli(begin) +
+ " ... " + Instant.ofEpochMilli(end) + ']';
}
}
diff --git a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/filter/TemporalFilterTest.java b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/filter/TemporalFilterTest.java
index f6fad0b..71c23ab 100644
--- a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/filter/TemporalFilterTest.java
+++ b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/filter/TemporalFilterTest.java
@@ -16,7 +16,7 @@
*/
package org.apache.sis.filter;
-import static org.apache.sis.util.privy.StandardDateFormat.MILLISECONDS_PER_DAY;
+import static org.apache.sis.util.privy.Constants.MILLISECONDS_PER_DAY;
// Test dependencies
import org.junit.jupiter.api.Test;
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 49db214..e03d430 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
@@ -18,6 +18,7 @@
import java.util.Collection;
import java.util.Date;
+import java.time.temporal.Temporal;
import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
@@ -30,8 +31,8 @@
import org.opengis.metadata.acquisition.Sequence;
import org.opengis.metadata.acquisition.Trigger;
import org.apache.sis.metadata.iso.ISOMetadata;
-import static org.apache.sis.metadata.privy.ImplementationHelper.toDate;
-import static org.apache.sis.metadata.privy.ImplementationHelper.toMilliseconds;
+import static org.apache.sis.util.privy.TemporalDate.toDate;
+import static org.apache.sis.util.privy.TemporalDate.toInstant;
/**
@@ -57,7 +58,7 @@
*
* @author Cédric Briançon (Geomatys)
* @author Martin Desruisseaux (Geomatys)
- * @version 1.4
+ * @version 1.5
* @since 0.3
*/
@XmlType(name = "MI_Event_Type", propOrder = {
@@ -75,7 +76,7 @@
/**
* Serial number for inter-operability with different versions.
*/
- private static final long serialVersionUID = -519920133287763009L;
+ private static final long serialVersionUID = 7862440773058520852L;
/**
* Initiator of the event.
@@ -93,9 +94,10 @@
private Sequence sequence;
/**
- * Time the event occurred, or {@link Long#MIN_VALUE} if none.
+ * Date and/or time the event occurred.
*/
- private long time = Long.MIN_VALUE;
+ @SuppressWarnings("serial") // Most implementations are serializable.
+ private Temporal time;
/**
* Objective or objectives satisfied by an event.
@@ -130,6 +132,7 @@
*
* @see #castOrCopy(Event)
*/
+ @SuppressWarnings("this-escape")
public DefaultEvent(final Event object) {
super(object);
if (object != null) {
@@ -137,7 +140,7 @@
trigger = object.getTrigger();
context = object.getContext();
sequence = object.getSequence();
- time = toMilliseconds(object.getTime());
+ time = toInstant(object.getTime());
expectedObjectives = copyCollection(object.getExpectedObjectives(), Objective.class);
relatedPass = object.getRelatedPass();
relatedSensors = copyCollection(object.getRelatedSensors(), Instrument.class);
@@ -256,6 +259,10 @@
/**
* 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}.
*/
@Override
@@ -270,8 +277,19 @@
* @param newValue the new time value.
*/
public void setTime(final Date newValue) {
+ setTime(toInstant(newValue));
+ }
+
+ /**
+ * Sets the date and/or time the event occurred.
+ *
+ * @param newValue the new time value.
+ *
+ * @since 1.5
+ */
+ public void setTime(final Temporal newValue) {
checkWritePermission(time);
- time = toMilliseconds(newValue);
+ time = 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 f2f1bf6..a9470eb 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
@@ -87,7 +87,7 @@
* @author Cédric Briançon (Geomatys)
* @author Martin Desruisseaux (Geomatys)
* @author Cullen Rombach (Image Matters)
- * @version 1.4
+ * @version 1.5
* @since 0.3
*/
@XmlSchema(location="https://schemas.isotc211.org/19115/-3/mac/1.0/mac.xsd",
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 cb20155..ebf05da 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
@@ -17,6 +17,7 @@
package org.apache.sis.metadata.iso.citation;
import java.util.Date;
+import java.time.temporal.Temporal;
import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
@@ -24,8 +25,8 @@
import org.opengis.metadata.citation.DateType;
import org.apache.sis.metadata.TitleProperty;
import org.apache.sis.metadata.iso.ISOMetadata;
-import static org.apache.sis.metadata.privy.ImplementationHelper.toDate;
-import static org.apache.sis.metadata.privy.ImplementationHelper.toMilliseconds;
+import static org.apache.sis.util.privy.TemporalDate.toDate;
+import static org.apache.sis.util.privy.TemporalDate.toInstant;
/**
@@ -47,7 +48,7 @@
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @author Cédric Briançon (Geomatys)
- * @version 1.4
+ * @version 1.5
* @since 0.3
*/
@TitleProperty(name = "date")
@@ -60,13 +61,13 @@
/**
* Serial number for inter-operability with different versions.
*/
- private static final long serialVersionUID = 5140213754542273710L;
+ private static final long serialVersionUID = 1032356967666782327L;
/**
- * Reference date for the cited resource in milliseconds elapsed sine January 1st, 1970,
- * or {@link Long#MIN_VALUE} if none.
+ * Reference date for the cited resource.
*/
- private long date = Long.MIN_VALUE;
+ @SuppressWarnings("serial") // Most implementations are serializable.
+ private Temporal date;
/**
* Event used for reference date.
@@ -82,11 +83,28 @@
/**
* Constructs a citation date initialized to the given date.
*
+ * @param date the reference date for the cited resource, or {@code null} if unknown.
+ * @param dateType the event used for reference date, or {@code null} if unknown.
+ *
+ * @since 1.5
+ */
+ public DefaultCitationDate(final Temporal date, final DateType dateType) {
+ this.date = date;
+ this.dateType = dateType;
+ }
+
+ /**
+ * Constructs a citation date initialized to the given date.
+ *
* @param date the reference date for the cited resource.
* @param dateType the event used for reference date.
+ *
+ * @deprecated Replaced by {@link #DefaultCitationDate(Temporal, DateType)}
+ * in order to transition to {@code java.time} API.
*/
+ @Deprecated(since="1.5", forRemoval=true)
public DefaultCitationDate(final Date date, final DateType dateType) {
- this.date = toMilliseconds(date);
+ this.date = toInstant(date);
this.dateType = dateType;
}
@@ -102,7 +120,7 @@
public DefaultCitationDate(final CitationDate object) {
super(object);
if (object != null) {
- date = toMilliseconds(object.getDate());
+ date = toInstant(object.getDate());
dateType = object.getDateType();
}
}
@@ -135,6 +153,10 @@
/**
* 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}.
*/
@Override
@@ -149,8 +171,19 @@
* @param newValue the new date.
*/
public void setDate(final Date newValue) {
- checkWritePermission(toDate(date));
- date = toMilliseconds(newValue);
+ setDate(toInstant(newValue));
+ }
+
+ /**
+ * Sets the reference date for the cited resource.
+ *
+ * @param newValue the new date.
+ *
+ * @since 1.5
+ */
+ public void setDate(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 e314180..3d33901 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
@@ -87,7 +87,7 @@
* @author Touraïvane (IRD)
* @author Cédric Briançon (Geomatys)
* @author Cullen Rombach (Image Matters)
- * @version 1.4
+ * @version 1.5
* @since 0.3
*/
@XmlSchema(location="https://schemas.isotc211.org/19115/-3/cit/1.0/cit.xsd",
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java
index 7e7ae5b..41e9069 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java
@@ -17,7 +17,9 @@
package org.apache.sis.metadata.iso.extent;
import java.util.Date;
+import java.util.Optional;
import java.time.Instant;
+import java.time.temporal.Temporal;
import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.XmlSeeAlso;
import jakarta.xml.bind.annotation.XmlElement;
@@ -30,6 +32,7 @@
import org.apache.sis.metadata.iso.ISOMetadata;
import org.apache.sis.metadata.privy.ReferencingServices;
import org.apache.sis.pending.temporal.TemporalUtilities;
+import org.apache.sis.util.privy.TemporalDate;
import org.apache.sis.xml.NilObject;
import org.apache.sis.xml.NilReason;
@@ -46,8 +49,8 @@
*
* In addition to the standard properties, SIS provides the following methods:
* <ul>
- * <li>{@link #getStartTime()} for fetching the start time from the temporal primitive.</li>
- * <li>{@link #getEndTime()} for fetching the end time from the temporal primitive.</li>
+ * <li>{@link #getBeginning()} for fetching the start time from the temporal primitive.</li>
+ * <li>{@link #getEnding()} for fetching the end time from the temporal primitive.</li>
* <li>{@link #setBounds(Date, Date)} for setting the extent from the given start and end time.</li>
* <li>{@link #setBounds(Envelope)} for setting the extent from the given envelope.</li>
* </ul>
@@ -138,9 +141,6 @@
/**
* Returns the date and time for the content of the dataset.
- * If no extent has been {@linkplain #setExtent(TemporalPrimitive) explicitly set},
- * then this method will build an extent from the {@linkplain #getStartTime() start
- * time} and {@linkplain #getEndTime() end time} if any.
*
* @return the date and time for the content, or {@code null}.
*/
@@ -161,31 +161,56 @@
}
/**
- * Infers a value from the extent as a {@link Date} object.
+ * Infers a value from the extent as a {@code Instant} object.
*
- * @param begin {@code true} if we are asking for the start time,
- * or {@code false} for the end time.
- * @return the requested time as a Java date, or {@code null} if none.
+ * @param begin {@code true} for the start time, or {@code false} for the end time.
+ * @return the requested time as an instant, or {@code null} if none.
*/
- static Date getTime(final TemporalPrimitive extent, final boolean begin) {
+ static Instant getBound(final TemporalPrimitive extent, final boolean begin) {
if (extent instanceof Period) {
var p = (Period) extent;
- Instant time = begin ? p.getBeginning() : p.getEnding();
- if (time != null) {
- return Date.from(time);
- }
+ return begin ? p.getBeginning() : p.getEnding();
}
return null;
}
/**
+ * Returns the start of the temporal range for the content of the dataset.
+ * This method tries to infer this value from the {@linkplain #getExtent() extent}.
+ * The returned object is often an {@link Instant}, but not necessarily.
+ *
+ * @return the start of the temporal range.
+ *
+ * @since 1.5
+ */
+ public Optional<Temporal> getBeginning() {
+ return Optional.ofNullable(getBound(extent, true));
+ }
+
+ /**
+ * Returns the end of the temporal range for the content of the dataset.
+ * This method tries to infer this value from the {@linkplain #getExtent() extent}.
+ * The returned object is often an {@link Instant}, but not necessarily.
+ *
+ * @return the end of the temporal range.
+ *
+ * @since 1.5
+ */
+ public Optional<Temporal> getEnding() {
+ return Optional.ofNullable(getBound(extent, false));
+ }
+
+ /**
* The start date and time for the content of the dataset.
* This method tries to infer it from the {@linkplain #getExtent() extent}.
*
* @return the start time, or {@code null} if none.
+ *
+ * @deprecated Replaced by {@link #getBeginning()} in order to transition to {@code java.time} API.
*/
+ @Deprecated(since="1.5", forRemoval=true)
public Date getStartTime() {
- return getTime(extent, true);
+ return TemporalDate.toDate(getBeginning().orElse(null));
}
/**
@@ -193,9 +218,12 @@
* This method tries to infer it from the {@linkplain #getExtent() extent}.
*
* @return the end time, or {@code null} if none.
+ *
+ * @deprecated Replaced by {@link #getEnding()} in order to transition to {@code java.time} API.
*/
+ @Deprecated(since="1.5", forRemoval=true)
public Date getEndTime() {
- return getTime(extent, false);
+ return TemporalDate.toDate(getEnding().orElse(null));
}
/**
@@ -204,13 +232,26 @@
*
* @param startTime the start date and time for the content of the dataset, or {@code null} if none.
* @param endTime the end date and time for the content of the dataset, or {@code null} if none.
+ *
+ * @deprecated Replaced by {@link #setBounds(Temporal, Temporal)} in order to transition to {@code java.time} API.
*/
- public void setBounds(final Date startTime, final Date endTime) throws UnsupportedOperationException {
- TemporalPrimitive value = null;
- if (startTime != null || endTime != null) {
- value = TemporalUtilities.createPeriod(startTime, endTime);
- }
- setExtent(value);
+ @Deprecated(since="1.5", forRemoval=true)
+ public void setBounds(final Date startTime, final Date endTime) {
+ setBounds((startTime == null) ? null : startTime.toInstant(),
+ (endTime == null) ? null : endTime.toInstant());
+ }
+
+ /**
+ * Sets the temporal extent to the specified values. This convenience method creates a temporal
+ * primitive for the given dates and/or times, then invokes {@link #setExtent(TemporalPrimitive)}.
+ *
+ * @param startTime the start date and time for the content of the dataset, or {@code null} if none.
+ * @param endTime the end date and time for the content of the dataset, or {@code null} if none.
+ *
+ * @since 1.5
+ */
+ public void setBounds(final Temporal startTime, final Temporal endTime) {
+ setExtent(TemporalUtilities.createPeriod(startTime, endTime));
}
/**
@@ -222,7 +263,7 @@
* module is available on the module path.</p>
*
* @param envelope the envelope to use for setting this temporal extent.
- * @throws UnsupportedOperationException if the referencing module or the temporal module is not on the module path.
+ * @throws UnsupportedOperationException if the referencing module is not on the module path.
* @throws TransformException if the envelope cannot be transformed to a temporal extent.
*
* @see DefaultExtent#addElements(Envelope)
@@ -255,21 +296,21 @@
if (extent == null || (ot instanceof NilObject)) {
extent = ot;
} else {
- Date t0 = getTime(extent, true);
- Date t1 = getTime(extent, false);
- Date h0 = getTime(ot, true);
- Date h1 = getTime(ot, false);
+ Instant t0 = getBound(extent, true);
+ Instant t1 = getBound(extent, false);
+ Instant h0 = getBound(ot, true);
+ Instant h1 = getBound(ot, false);
boolean changed = false;
- if (h0 != null && (t0 == null || h0.after(t0))) {
+ if (h0 != null && (t0 == null || h0.isAfter(t0))) {
t0 = h0;
changed = true;
}
- if (h1 != null && (t1 == null || h1.before(t1))) {
+ if (h1 != null && (t1 == null || h1.isBefore(t1))) {
t1 = h1;
changed = true;
}
if (changed) {
- if (t0 != null && t1 != null && t0.after(t1)) {
+ if (t0 != null && t1 != null && t0.isAfter(t1)) {
extent = NilReason.MISSING.createNilObject(TemporalPrimitive.class);
} else {
setBounds(t0, t1);
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/Extents.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/Extents.java
index d5690b8..2d45a32 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/Extents.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/extent/Extents.java
@@ -28,7 +28,11 @@
import java.util.stream.Stream;
import java.util.function.Function;
import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
import static java.lang.Math.*;
+import java.time.ZoneId;
+import java.time.Instant;
+import java.time.DateTimeException;
import javax.measure.Unit;
import org.opengis.geometry.Envelope;
import org.opengis.geometry.DirectPosition;
@@ -57,6 +61,7 @@
import org.apache.sis.measure.Longitude;
import org.apache.sis.measure.MeasurementRange;
import org.apache.sis.measure.Range;
+import org.apache.sis.pending.jdk.JDK23;
import org.apache.sis.util.OptionalCandidate;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ComparisonMode;
@@ -65,8 +70,9 @@
import org.apache.sis.util.iso.Types;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.resources.Errors;
-import static org.apache.sis.util.collection.Containers.isNullOrEmpty;
+import org.apache.sis.util.privy.TemporalDate;
import static org.apache.sis.util.privy.CollectionsExt.nonNull;
+import static org.apache.sis.util.collection.Containers.isNullOrEmpty;
import static org.apache.sis.metadata.privy.ReferencingServices.AUTHALIC_RADIUS;
// Specific to the main branch:
@@ -485,31 +491,53 @@
* @return a time range created from the given extent, or {@code null} if none.
*
* @since 0.4
+ *
+ * @deprecated Replaced by {@link #getTimeRange(Extent, ZoneId)} in order to transition to {@code java.time} API.
*/
- @OptionalCandidate
+ @Deprecated(since="1.5", forRemoval=true)
public static Range<Date> getTimeRange(final Extent extent) {
- Date min = null;
- Date max = null;
- if (extent != null) {
- for (final TemporalExtent t : nonNull(extent.getTemporalElements())) {
- final Date startTime, endTime;
- if (t instanceof DefaultTemporalExtent) {
- final DefaultTemporalExtent dt = (DefaultTemporalExtent) t;
- startTime = dt.getStartTime(); // Maybe user has overridden those methods.
- endTime = dt.getEndTime();
- } else {
- final TemporalPrimitive p = t.getExtent();
- startTime = DefaultTemporalExtent.getTime(p, true);
- endTime = DefaultTemporalExtent.getTime(p, false);
- }
- if (startTime != null && (min == null || startTime.before(min))) min = startTime;
- if ( endTime != null && (max == null || endTime.after (max))) max = endTime;
+ return onTimeRange(extent, null, (min, max) -> {
+ if (min == null && max == null) {
+ return null;
}
- }
- if (min == null && max == null) {
- return null;
- }
- return new Range<>(Date.class, min, true, max, true);
+ return new Range<>(Date.class, TemporalDate.toDate(min), true, TemporalDate.toDate(max), true);
+ }).orElse(null);
+ }
+
+ /**
+ * Returns the union of all time ranges found in the given extent.
+ *
+ * @param extent the extent to convert to a time range, or {@code null}.
+ * @param zone the timezone to use if a time is local, or {@code null} if none.
+ * @return a time range created from the given extent.
+ * @throws DateTimeException if a temporal value cannot be converted to an instant.
+ *
+ * @since 1.5
+ */
+ public static Optional<Range<Instant>> getTimeRange(final Extent extent, final ZoneId zone) {
+ return onTimeRange(extent, zone, (min, max) -> {
+ if (min == null && max == null) {
+ return null;
+ }
+ return new Range<>(Instant.class, min, true, max, true);
+ });
+ }
+
+ /**
+ * Returns a date in the {@linkplain Extent#getTemporalElements() temporal elements} of the given extent.
+ *
+ * @param extent the extent from which to get an instant, or {@code null}.
+ * @param location 0 for the start time, 1 for the end time, 0.5 for the average time, or the
+ * coefficient (usually in the [0 … 1] range) for interpolating an instant.
+ * @return an instant interpolated at the given location, or {@code null} if none.
+ *
+ * @since 0.4
+ *
+ * @deprecated Replaced by {@link #getTimeRange(Extent, ZoneId)} in order to transition to {@code java.time} API.
+ */
+ @Deprecated(since="1.5", forRemoval=true)
+ public static Date getDate(final Extent extent, final double location) {
+ return TemporalDate.toDate(getInstant(extent, null, location).orElse(null));
}
/**
@@ -523,8 +551,8 @@
*
* Special cases:
* <ul>
- * <li>If {@code location} is 0, then this method returns the {@linkplain DefaultTemporalExtent#getStartTime() start time}.</li>
- * <li>If {@code location} is 1, then this method returns the {@linkplain DefaultTemporalExtent#getEndTime() end time}.</li>
+ * <li>If {@code location} is 0, then this method returns the {@linkplain DefaultTemporalExtent#getBeginning() start time}.</li>
+ * <li>If {@code location} is 1, then this method returns the {@linkplain DefaultTemporalExtent#getEnding() end time}.</li>
* <li>If {@code location} is 0.5, then this method returns the average of start time and end time.</li>
* <li>If {@code location} is outside the [0 … 1] range, then the result will be outside the temporal extent.</li>
* </ul>
@@ -534,34 +562,49 @@
* coefficient (usually in the [0 … 1] range) for interpolating an instant.
* @return an instant interpolated at the given location, or {@code null} if none.
*
- * @since 0.4
+ * @since 1.5
*/
- @OptionalCandidate
- public static Date getDate(final Extent extent, final double location) {
+ public static Optional<Instant> getInstant(final Extent extent, final ZoneId zone, final double location) {
ArgumentChecks.ensureFinite("location", location);
- Date min = null;
- Date max = null;
+ return onTimeRange(extent, zone, (min, max) -> {
+ if (min == null) return max;
+ if (max == null) return min;
+ return min.plusMillis(Math.round(location * JDK23.until(min, max).toMillis()));
+ });
+ }
+
+ /**
+ * Returns the result of applying the given function on the minimum and maximal temporal value.
+ *
+ * @param <T> type of value computed by the function.
+ * @param extent the extent on which to apply a function, or {@code null}.
+ * @param zone the timezone to use if a time is local, or {@code null} if none.
+ * @param operator the function to apply on the start and end time. Those times may be null.
+ * @return the result of applying the given function on the start and end time.
+ */
+ private static <T> Optional<T> onTimeRange(final Extent extent, final ZoneId zone,
+ final BiFunction<Instant,Instant,T> operator)
+ {
+ Instant min = null;
+ Instant max = null;
if (extent != null) {
for (final TemporalExtent t : nonNull(extent.getTemporalElements())) {
- Date startTime = null;
- Date endTime = null;
+ final Instant startTime, endTime;
if (t instanceof DefaultTemporalExtent) {
- final DefaultTemporalExtent dt = (DefaultTemporalExtent) t;
- if (location != 1) startTime = dt.getStartTime(); // Maybe user has overridden those methods.
- if (location != 0) endTime = dt.getEndTime();
+ final var dt = (DefaultTemporalExtent) t;
+ // Maybe user has overridden those methods.
+ startTime = TemporalDate.toInstant(dt.getBeginning().orElse(null), zone);
+ endTime = TemporalDate.toInstant(dt.getEnding() .orElse(null), zone);
} else {
final TemporalPrimitive p = t.getExtent();
- if (location != 1) startTime = DefaultTemporalExtent.getTime(p, true);
- if (location != 0) endTime = DefaultTemporalExtent.getTime(p, false);
+ startTime = DefaultTemporalExtent.getBound(p, true);
+ endTime = DefaultTemporalExtent.getBound(p, false);
}
- if (startTime != null && (min == null || startTime.before(min))) min = startTime;
- if ( endTime != null && (max == null || endTime.after (max))) max = endTime;
+ if (startTime != null && (min == null || startTime.isBefore(min))) min = startTime;
+ if ( endTime != null && (max == null || endTime.isAfter (max))) max = endTime;
}
}
- if (min == null) return max;
- if (max == null) return min;
- final long startTime = min.getTime();
- return new Date(Math.addExact(startTime, Math.round((max.getTime() - startTime) * location)));
+ return Optional.ofNullable(operator.apply(min, max));
}
/**
@@ -789,7 +832,7 @@
* @param e2 the second extent, or {@code null}.
* @param constructor copy constructor of metadata implementation class.
* @param operator the union or intersection operator to apply.
- * @return
+ * @return the intersection or union of the given metadata objects.
*/
@SuppressWarnings("unchecked") // Workaround for Java above-cited compiler restriction.
private static <I, C extends ISOMetadata> I apply(final I e1, final I e2,
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/legacy/TemporalToDate.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/legacy/TemporalToDate.java
index 6b71eff..2249cde 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/legacy/TemporalToDate.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/legacy/TemporalToDate.java
@@ -16,13 +16,12 @@
*/
package org.apache.sis.metadata.iso.legacy;
-import java.time.Instant;
-import java.time.temporal.ChronoField;
import java.time.temporal.Temporal;
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
+import org.apache.sis.util.privy.TemporalDate;
/**
@@ -59,6 +58,7 @@
/**
* Returns an iterator over the dates in this collection.
+ * If a temporal object does not specify its timezone, then UTC is assumed.
*
* @return an iterator over the dates.
*/
@@ -73,13 +73,8 @@
/** Returns the next temporal object, converted to a date. */
@Override public Date next() {
- final Temporal t = dates.next();
- if (t == null) return null;
- if (t instanceof Instant) {
- return Date.from((Instant) t);
- }
- // Following may throw `DateTimeException` if the temporal does not support the field.
- return new Date(Math.multiplyExact(t.getLong(ChronoField.INSTANT_SECONDS), 1000));
+ // Following may throw `DateTimeException` if the temporal does not support a required field.
+ return TemporalDate.toDate(dates.next());
}
/** Remove the last date returned by the iterator. */
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/lineage/DefaultProcessStep.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/lineage/DefaultProcessStep.java
index 45ea41c..9fa6dcf 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/lineage/DefaultProcessStep.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/lineage/DefaultProcessStep.java
@@ -34,9 +34,9 @@
import org.apache.sis.metadata.iso.ISOMetadata;
import org.apache.sis.util.iso.Types;
import org.apache.sis.xml.bind.FilterByVersion;
-import org.apache.sis.xml.privy.LegacyNamespaces;
import org.apache.sis.xml.bind.gml.TM_Primitive;
import org.apache.sis.xml.bind.metadata.MD_Scope;
+import org.apache.sis.xml.privy.LegacyNamespaces;
import org.apache.sis.pending.temporal.TemporalUtilities;
// Specific to the main and geoapi-3.1 branches:
@@ -317,7 +317,7 @@
*/
@Deprecated(since="1.0")
public void setDate(final Date newValue) {
- setStepDateTime(TemporalUtilities.createInstant(newValue));
+ setStepDateTime(TemporalUtilities.createInstant(newValue == null ? null : newValue.toInstant()));
}
/**
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
index 2cec5bf..2d813be 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultMaintenanceInformation.java
@@ -160,6 +160,7 @@
*
* @see #castOrCopy(MaintenanceInformation)
*/
+ @SuppressWarnings("this-escape")
public DefaultMaintenanceInformation(final MaintenanceInformation object) {
super(object);
if (object != null) {
@@ -305,7 +306,8 @@
}
}
if (newValue != null) {
- final CitationDate date = new DefaultCitationDate(newValue, NEXT_UPDATE);
+ @SuppressWarnings("removal")
+ final var date = new DefaultCitationDate(newValue, NEXT_UPDATE);
if (dates != null) {
dates.add(date);
} else {
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/privy/ImplementationHelper.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/privy/ImplementationHelper.java
index 84ab9d4..def420f 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/privy/ImplementationHelper.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/privy/ImplementationHelper.java
@@ -54,7 +54,7 @@
/**
* Returns the milliseconds value of the given date, or {@link Long#MIN_VALUE}
- * if the date us null.
+ * if the date is null.
*
* @param value the date, or {@code null}.
* @return the time in milliseconds, or {@code Long.MIN_VALUE} 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 c83c97f..aaa0a1b 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
@@ -18,7 +18,10 @@
import java.util.Date;
import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.temporal.Temporal;
import org.opengis.temporal.TemporalPrimitive;
+import org.apache.sis.util.privy.TemporalDate;
// Specific to the main branch:
import org.apache.sis.pending.geoapi.temporal.Period;
@@ -42,27 +45,44 @@
*
* @param time the date for which to create instant, or {@code null}.
* @return the instant, or {@code null} if the given time was null.
- * @throws UnsupportedOperationException if the temporal factory is not available on the module path.
*/
- public static TemporalPrimitive createInstant(final Date time) throws UnsupportedOperationException {
- if (time == null) return null;
- final Instant t = time.toInstant();
- return new DefaultPeriod(t, t);
+ public static TemporalPrimitive createInstant(final Date time) {
+ return (time == null) ? null : createInstant(time.toInstant());
}
/**
- * Creates a period for the given begin and end dates.
+ * Creates an instant for the given Java temporal instant.
*
- * @param begin the begin date (inclusive), or {@code null}.
- * @param end the end date (inclusive), or {@code null}.
- * @return the period, or {@code null} if both arguments are null.
- * @throws UnsupportedOperationException if the temporal factory is not available on the module path.
+ * @param time the date for which to create instant, or {@code null}.
+ * @return the instant, or {@code null} if the given time was null.
*/
- public static TemporalPrimitive createPeriod(final Date begin, final Date end) throws UnsupportedOperationException {
- if (begin == null && end == null) return null;
- return new DefaultPeriod(
- (begin != null) ? begin.toInstant() : null,
- (end != null) ? end.toInstant() : null);
+ public static TemporalPrimitive createInstant(final Instant time) {
+ return (time == null) ? null : new DefaultPeriod(time, time);
+ }
+
+ /**
+ * 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}.
+ * @return the period, or {@code null} if both arguments are null.
+ */
+ public static TemporalPrimitive createPeriod(final Instant begin, final Instant end) {
+ return (begin == null && end == null) ? null : new DefaultPeriod(begin, end);
+ }
+
+ /**
+ * 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}.
+ * @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 createPeriod(TemporalDate.toInstant(begin, ZoneOffset.UTC),
+ TemporalDate.toInstant(end, ZoneOffset.UTC));
}
/**
@@ -122,7 +142,7 @@
var p = (Period) time;
Instant instant;
if ((instant = p.getEnding()) != null || (instant = p.getBeginning()) != null) {
- return Date.from(instant);
+ return TemporalDate.toDate(instant);
}
}
return null;
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/TM_Primitive.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/TM_Primitive.java
index 05c5097..5fcac07 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/TM_Primitive.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/TM_Primitive.java
@@ -16,7 +16,6 @@
*/
package org.apache.sis.xml.bind.gml;
-import java.util.Date;
import java.time.Instant;
import jakarta.xml.bind.annotation.XmlElement;
import org.opengis.temporal.TemporalPrimitive;
@@ -108,10 +107,10 @@
metadata = null; // Cleaned first in case of failure.
if (period != null) {
final Context context = Context.current();
- final Date begin = toDate(context, period.begin);
- final Date end = toDate(context, period.end);
+ final Instant begin = toInstant(context, period.begin);
+ final Instant end = toInstant(context, period.end);
if (begin != null || end != null) {
- if (begin != null && end != null && end.before(begin)) {
+ if (begin != null && end != null && end.isBefore(begin)) {
/*
* Be tolerant - we can treat such case as an empty range, which is a similar
* approach to what JDK does for Rectangle width and height. We will log with
@@ -120,11 +119,9 @@
*/
Context.warningOccured(context, TemporalPrimitive.class,
"setTimePeriod", Errors.class, Errors.Keys.IllegalRange_2, begin, end);
- } else try {
+ } else {
metadata = TemporalUtilities.createPeriod(begin, end);
period.copyIdTo(metadata);
- } catch (UnsupportedOperationException e) {
- warningOccured("setTimePeriod", e);
}
}
}
@@ -139,31 +136,19 @@
public final void setTimeInstant(final TimeInstant instant) {
metadata = null; // Cleaned first in case of failure.
if (instant != null) {
- final Date position = XmlUtilities.toDate(Context.current(), instant.timePosition);
- if (position != null) try {
+ final Instant position = XmlUtilities.toInstant(Context.current(), instant.timePosition);
+ if (position != null) {
metadata = TemporalUtilities.createInstant(position);
instant.copyIdTo(metadata);
- } catch (UnsupportedOperationException e) {
- warningOccured("setTimeInstant", e);
}
}
}
/**
- * Returns the date of the given bounds, or {@code null} if none.
+ * Returns the instant of the given bounds, or {@code null} if none.
*/
- private static Date toDate(final Context context, final TimePeriodBound bound) {
- return (bound != null) ? XmlUtilities.toDate(context, bound.calendar()) : null;
- }
-
- /**
- * Reports a warning for the given exception.
- *
- * @param method the name of the method to declare in the log record.
- * @param e the exception.
- */
- private static void warningOccured(final String method, final Exception e) {
- Context.warningOccured(Context.current(), TM_Primitive.class, method, e, true);
+ private static Instant toInstant(final Context context, final TimePeriodBound bound) {
+ return (bound != null) ? XmlUtilities.toInstant(context, bound.calendar()) : null;
}
/**
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/TemporalAdapter.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/TemporalAdapter.java
new file mode 100644
index 0000000..7d9416d
--- /dev/null
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/TemporalAdapter.java
@@ -0,0 +1,67 @@
+/*
+ * 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.xml.bind.gml;
+
+import java.time.temporal.Temporal;
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.datatype.DatatypeConfigurationException;
+import jakarta.xml.bind.annotation.adapters.XmlAdapter;
+import org.apache.sis.xml.privy.XmlUtilities;
+import org.apache.sis.xml.bind.Context;
+
+
+/**
+ * JAXB adapter wrapping a temporal value.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public final class TemporalAdapter extends XmlAdapter<XMLGregorianCalendar, Temporal> {
+ /**
+ * Empty constructor for JAXB only.
+ */
+ public TemporalAdapter() {
+ }
+
+ /**
+ * Converts a date read from a XML stream to the object which will contain the value.
+ * JAXB calls automatically this method at unmarshalling time.
+ *
+ * @param value the XML date, or {@code null}.
+ * @return the temporal object, or {@code null}.
+ */
+ @Override
+ public Temporal unmarshal(final XMLGregorianCalendar value) {
+ return XmlUtilities.toTemporal(Context.current(), value);
+ }
+
+ /**
+ * Converts the date to the object to be marshalled in a XML file or stream.
+ * JAXB calls automatically this method at marshalling time.
+ *
+ * @param value the temporal object, or {@code null}.
+ * @return the XML date, or {@code null}.
+ */
+ @Override
+ public XMLGregorianCalendar marshal(final Temporal value) {
+ try {
+ return XmlUtilities.toXML(Context.current(), value);
+ } catch (DatatypeConfigurationException e) {
+ Context.warningOccured(Context.current(), TemporalAdapter.class, "marshal", e, true);
+ return null;
+ }
+ }
+}
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/TimePeriodBound.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/TimePeriodBound.java
index 288abe6..da5c230 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/TimePeriodBound.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/TimePeriodBound.java
@@ -163,6 +163,7 @@
*/
@Override
XMLGregorianCalendar calendar() {
+ @SuppressWarnings("LocalVariableHidesMemberVariable")
final TimeInstant timeInstant = this.timeInstant;
return (timeInstant != null) ? timeInstant.timePosition : null;
}
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/UniversalTimeAdapter.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/UniversalTimeAdapter.java
index 7379d4f..1c91065 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/UniversalTimeAdapter.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/gml/UniversalTimeAdapter.java
@@ -42,7 +42,7 @@
/**
* The timezone of the date to marshal with this adapter.
*/
- private static final TimeZone UTC = TimeZone.getTimeZone(org.apache.sis.util.privy.StandardDateFormat.UTC);
+ private static final TimeZone UTC = TimeZone.getTimeZone(org.apache.sis.util.privy.Constants.UTC);
/**
* Empty constructor for JAXB only.
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/privy/XmlUtilities.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/privy/XmlUtilities.java
index 8b5ea3c..0368141 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/privy/XmlUtilities.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/privy/XmlUtilities.java
@@ -192,22 +192,21 @@
* @return the XML calendar, or {@code null} if {@code date} was null.
* @throws DatatypeConfigurationException if the factory cannot be created.
*/
- public static XMLGregorianCalendar toXML(final Context context, final Temporal date) throws DatatypeConfigurationException {
+ public static XMLGregorianCalendar toXML(final Context context, Temporal date) throws DatatypeConfigurationException {
if (date == null) {
return null;
}
- final XMLGregorianCalendar xml = getDatatypeFactory().newXMLGregorianCalendar();
if (date instanceof Instant) {
final TimeZone zone = (context != null) ? context.getTimeZone() : null;
final ZoneId zid = (zone != null) ? zone.toZoneId() : ZoneId.systemDefault();
- final ZonedDateTime t = ZonedDateTime.ofInstant((Instant) date, zid);
- for (int i=0; i<FIELDS.length; i++) {
- SETTERS[i].accept(xml, t.get(FIELDS[i]));
- }
- } else {
- for (int i=0; i<FIELDS.length; i++) {
- final ChronoField field = FIELDS[i];
- if (date.isSupported(field)) {
+ date = ZonedDateTime.ofInstant((Instant) date, zid);
+ }
+ final XMLGregorianCalendar xml = getDatatypeFactory().newXMLGregorianCalendar();
+ for (int i=0; i<FIELDS.length; i++) {
+ final ChronoField field = FIELDS[i];
+ if (date.isSupported(field)) {
+ final int n = date.get(field);
+ if (n != 0 || field != ChronoField.MILLI_OF_SECOND) {
SETTERS[i].accept(xml, date.get(field));
}
}
@@ -317,6 +316,20 @@
}
/**
+ * Converts the given XML Gregorian calendar to an instant.
+ * This method should be invoked only when the temporal object needs to be the {@link Instant} specialization.
+ * If the more generic {@link Temporal} type is okay, use {@link #toTemporal(Context, XMLGregorianCalendar)}.
+ *
+ * @param context the current (un)marshalling context, or {@code null} if none.
+ * @param xml the XML calendar to convert to a date, or {@code null}.
+ * @return the instant, or {@code null} if {@code xml} was null.
+ */
+ public static Instant toInstant(final Context context, final XMLGregorianCalendar xml) {
+ final Date date = toDate(context, xml);
+ return (date != null) ? date.toInstant() : null;
+ }
+
+ /**
* Converts the given XML Gregorian calendar to a date.
*
* @param context the current (un)marshalling context, or {@code null} if none.
diff --git a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java
index 9f0bcae..93c2582 100644
--- a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java
+++ b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java
@@ -17,6 +17,7 @@
package org.apache.sis.metadata.iso.extent;
import java.util.List;
+import java.time.Instant;
import java.net.URL;
import java.io.InputStream;
import jakarta.xml.bind.JAXBException;
@@ -31,7 +32,6 @@
import static org.junit.jupiter.api.Assertions.*;
import org.apache.sis.metadata.xml.TestUsingFile;
import static org.apache.sis.metadata.Assertions.assertXmlEquals;
-import static org.apache.sis.test.TestUtilities.date;
/**
@@ -73,13 +73,13 @@
*/
@Test
public void testIntersect() {
- final DefaultGeographicBoundingBox bounds1 = new DefaultGeographicBoundingBox(10, 20, 30, 40);
- final DefaultGeographicBoundingBox bounds2 = new DefaultGeographicBoundingBox(16, 18, 31, 42);
- final DefaultGeographicBoundingBox clip = new DefaultGeographicBoundingBox(15, 25, 26, 32);
- final DefaultGeographicBoundingBox expected1 = new DefaultGeographicBoundingBox(15, 20, 30, 32);
- final DefaultGeographicBoundingBox expected2 = new DefaultGeographicBoundingBox(16, 18, 31, 32);
- final DefaultExtent e1 = new DefaultExtent("Somewhere", bounds1, null, null);
- final DefaultExtent e2 = new DefaultExtent("Somewhere", clip, null, null);
+ final var bounds1 = new DefaultGeographicBoundingBox(10, 20, 30, 40);
+ final var bounds2 = new DefaultGeographicBoundingBox(16, 18, 31, 42);
+ final var clip = new DefaultGeographicBoundingBox(15, 25, 26, 32);
+ final var expected1 = new DefaultGeographicBoundingBox(15, 20, 30, 32);
+ final var expected2 = new DefaultGeographicBoundingBox(16, 18, 31, 32);
+ final var e1 = new DefaultExtent("Somewhere", bounds1, null, null);
+ final var e2 = new DefaultExtent("Somewhere", clip, null, null);
e1.getGeographicElements().add(bounds2);
e1.intersect(e2);
assertEquals("Somewhere", e1.getDescription().toString());
@@ -125,14 +125,15 @@
* Compares the marshalling and unmarshalling of a {@link DefaultExtent} with XML in the given file.
*/
private void roundtrip(final Format format) throws JAXBException {
- final DefaultGeographicBoundingBox bbox = new DefaultGeographicBoundingBox(-99, -79, 14.9844, 31);
+ final var bbox = new DefaultGeographicBoundingBox(-99, -79, 14.9844, 31);
bbox.getIdentifierMap().put(IdentifierSpace.ID, "bbox");
- final DefaultTemporalExtent temporal = new DefaultTemporalExtent();
+ final var temporal = new DefaultTemporalExtent();
if (PENDING_FUTURE_SIS_VERSION) {
// This block needs a more complete sis-temporal module.
- temporal.setBounds(date("2010-01-27 13:26:10"), date("2010-08-27 13:26:10"));
+ temporal.setBounds(Instant.parse("2010-01-27T13:26:10Z"),
+ Instant.parse("2010-08-27T13:26:10Z"));
}
- final DefaultExtent extent = new DefaultExtent(null, bbox, null, temporal);
+ final var extent = new DefaultExtent(null, bbox, null, temporal);
assertMarshalEqualsFile(openTestFile(format), extent, format.schemaVersion, "xmlns:*", "xsi:schemaLocation");
assertEquals(extent, unmarshalFile(DefaultExtent.class, openTestFile(format)));
}
diff --git a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/DefaultTemporalExtentTest.java b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/DefaultTemporalExtentTest.java
new file mode 100644
index 0000000..2ad7e3d
--- /dev/null
+++ b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/extent/DefaultTemporalExtentTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.metadata.iso.extent;
+
+import java.time.Instant;
+import org.opengis.referencing.operation.TransformException;
+
+// Test dependencies
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+import org.apache.sis.test.TestCase;
+
+
+/**
+ * Tests {@link DefaultTemporalExtent}.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public final class DefaultTemporalExtentTest extends TestCase {
+ /**
+ * Creates a new test case.
+ */
+ public DefaultTemporalExtentTest() {
+ }
+
+ /**
+ * Tests {@link DefaultTemporalExtent#intersect(TemporalExtent)}.
+ *
+ * @throws TransformException if the transformation failed.
+ */
+ @Test
+ public void testTemporalIntersection() throws TransformException {
+ final var e1 = new DefaultTemporalExtent();
+ final var e2 = new DefaultTemporalExtent();
+ final Instant t1 = Instant.parse("2016-12-05T19:45:20Z");
+ final Instant t2 = Instant.parse("2017-02-18T02:12:50Z");
+ final Instant t3 = Instant.parse("2017-11-30T23:50:00Z");
+ final Instant t4 = Instant.parse("2018-05-20T12:30:45Z");
+ e1.setBounds(t1, t3);
+ e2.setBounds(t2, t4);
+ e1.intersect(e2);
+ assertEquals(t2, e1.getBeginning().orElseThrow(), "beginning");
+ assertEquals(t3, e1.getEnding().orElseThrow(), "ending");
+ }
+}
diff --git a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/bind/gml/TimePeriodTest.java b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/bind/gml/TimePeriodTest.java
index 4699f27..68da733 100644
--- a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/bind/gml/TimePeriodTest.java
+++ b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/bind/gml/TimePeriodTest.java
@@ -36,7 +36,6 @@
import org.apache.sis.xml.test.TestCase;
import static org.apache.sis.metadata.Assertions.assertXmlEquals;
import static org.apache.sis.test.TestUtilities.date;
-import static org.apache.sis.test.TestUtilities.format;
/**
@@ -92,8 +91,8 @@
" <gml:timePosition>1992-01-01T01:00:00.000+01:00</gml:timePosition>\n" +
"</gml:TimeInstant>\n", actual, "xmlns:*");
- final TimeInstant test = (TimeInstant) unmarshal(unmarshaller, actual);
- assertEquals("1992-01-01 00:00:00", format(XmlUtilities.toDate(context, test.timePosition)));
+ final var test = (TimeInstant) unmarshal(unmarshaller, actual);
+ assertEquals("1992-01-01T00:00:00Z", XmlUtilities.toInstant(context, test.timePosition).toString());
pool.recycle(marshaller);
pool.recycle(unmarshaller);
@@ -108,8 +107,8 @@
@Test
public void testPeriodGML2() throws JAXBException {
createContext();
- final TimePeriodBound begin = new TimePeriodBound.GML2(Instant.parse("1992-01-01T00:00:00Z"));
- final TimePeriodBound end = new TimePeriodBound.GML2(Instant.parse("2007-12-31T00:00:00Z"));
+ final var begin = new TimePeriodBound.GML2(Instant.parse("1992-01-01T00:00:00Z"));
+ final var end = new TimePeriodBound.GML2(Instant.parse("2007-12-31T00:00:00Z"));
testPeriod(begin, end,
"<gml:TimePeriod xmlns:gml=\"" + Namespaces.GML + "\">\n" +
" <gml:begin>\n" +
@@ -142,10 +141,10 @@
period.end = end;
final String actual = marshal(marshaller, period);
assertXmlEquals(expected, actual, "xmlns:*");
- final TimePeriod test = (TimePeriod) unmarshal(unmarshaller, actual);
+ final var test = (TimePeriod) unmarshal(unmarshaller, actual);
if (verifyValues) {
- assertEquals("1992-01-01 00:00:00", format(XmlUtilities.toDate(context, test.begin.calendar())));
- assertEquals("2007-12-31 00:00:00", format(XmlUtilities.toDate(context, test.end .calendar())));
+ assertEquals("1992-01-01T00:00:00Z", XmlUtilities.toInstant(context, test.begin.calendar()).toString());
+ assertEquals("2007-12-31T00:00:00Z", XmlUtilities.toInstant(context, test.end .calendar()).toString());
}
pool.recycle(marshaller);
pool.recycle(unmarshaller);
@@ -160,8 +159,8 @@
@Test
public void testPeriodGML3() throws JAXBException {
createContext();
- final TimePeriodBound begin = new TimePeriodBound.GML3(Instant.parse("1992-01-01T00:00:00Z"), "before");
- final TimePeriodBound end = new TimePeriodBound.GML3(Instant.parse("2007-12-31T00:00:00Z"), "after");
+ final var begin = new TimePeriodBound.GML3(Instant.parse("1992-01-01T00:00:00Z"), "before");
+ final var end = new TimePeriodBound.GML3(Instant.parse("2007-12-31T00:00:00Z"), "after");
testPeriod(begin, end,
"<gml:TimePeriod xmlns:gml=\"" + Namespaces.GML + "\">\n" +
" <gml:beginPosition>1992-01-01T01:00:00+01:00</gml:beginPosition>\n" +
@@ -178,8 +177,8 @@
@Test
public void testSimplifiedPeriodGML3() throws JAXBException {
createContext();
- final TimePeriodBound begin = new TimePeriodBound.GML3(Instant.parse("1992-01-01T23:00:00Z"), "before");
- final TimePeriodBound end = new TimePeriodBound.GML3(Instant.parse("2007-12-30T23:00:00Z"), "after");
+ final var begin = new TimePeriodBound.GML3(Instant.parse("1992-01-01T23:00:00Z"), "before");
+ final var end = new TimePeriodBound.GML3(Instant.parse("2007-12-30T23:00:00Z"), "after");
testPeriod(begin, end,
"<gml:TimePeriod xmlns:gml=\"" + Namespaces.GML + "\">\n" +
" <gml:beginPosition>1992-01-02</gml:beginPosition>\n" +
@@ -196,8 +195,8 @@
@Test
public void testBeforePeriodGML3() throws JAXBException {
createContext();
- final TimePeriodBound begin = new TimePeriodBound.GML3(null, "before");
- final TimePeriodBound end = new TimePeriodBound.GML3(Instant.parse("2007-12-30T23:00:00Z"), "after");
+ final var begin = new TimePeriodBound.GML3(null, "before");
+ final var end = new TimePeriodBound.GML3(Instant.parse("2007-12-30T23:00:00Z"), "after");
testPeriod(begin, end,
"<gml:TimePeriod xmlns:gml=\"" + Namespaces.GML + "\">\n" +
" <gml:beginPosition indeterminatePosition=\"before\"/>\n" +
@@ -214,8 +213,8 @@
@Test
public void testAfterPeriodGML3() throws JAXBException {
createContext();
- final TimePeriodBound begin = new TimePeriodBound.GML3(Instant.parse("1992-01-01T23:00:00Z"), "before");
- final TimePeriodBound end = new TimePeriodBound.GML3(null, "after");
+ final var begin = new TimePeriodBound.GML3(Instant.parse("1992-01-01T23:00:00Z"), "before");
+ final var end = new TimePeriodBound.GML3(null, "after");
testPeriod(begin, end,
"<gml:TimePeriod xmlns:gml=\"" + Namespaces.GML + "\">\n" +
" <gml:beginPosition>1992-01-02</gml:beginPosition>\n" +
diff --git a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/bind/lan/LanguageCodeTest.java b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/bind/lan/LanguageCodeTest.java
index bf2b96e..7249e95 100644
--- a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/bind/lan/LanguageCodeTest.java
+++ b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/bind/lan/LanguageCodeTest.java
@@ -27,7 +27,7 @@
import org.apache.sis.xml.MarshallerPool;
import org.apache.sis.xml.bind.cat.CodeListUID;
import org.apache.sis.xml.privy.LegacyNamespaces;
-import static org.apache.sis.util.privy.StandardDateFormat.UTC;
+import static org.apache.sis.util.privy.Constants.UTC;
// Test dependencies
import org.junit.jupiter.api.Test;
diff --git a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/privy/XmlUtilitiesTest.java b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/privy/XmlUtilitiesTest.java
index cc53d6f..2314f9f 100644
--- a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/privy/XmlUtilitiesTest.java
+++ b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/privy/XmlUtilitiesTest.java
@@ -61,10 +61,10 @@
@Test
public void testDateToXML() throws DatatypeConfigurationException, JAXBException {
createContext(false, Locale.FRANCE, "CET");
- final Date date = new Date(1230786000000L);
- final XMLGregorianCalendar calendar = XmlUtilities.toXML(context, date);
+ final Instant date = Instant.ofEpochMilli(1230786000000L);
+ final XMLGregorianCalendar calendar = XmlUtilities.toXML(context, Date.from(date));
assertEquals("2009-01-01T06:00:00.000+01:00", calendar.toString());
- assertEquals(date, XmlUtilities.toDate(context, calendar));
+ assertEquals(date, XmlUtilities.toInstant(context, calendar));
calendar.setMillisecond(FIELD_UNDEFINED);
assertEquals("2009-01-01T06:00:00+01:00", calendar.toString());
@@ -85,21 +85,21 @@
t = Instant.ofEpochMilli(1230786000000L);
calendar = XmlUtilities.toXML(context, t);
- assertEquals("2009-01-01T14:00:00.000+09:00", calendar.toString());
+ assertEquals("2009-01-01T14:00:00+09:00", calendar.toString());
t = OffsetDateTime.parse("2009-01-01T06:00:00+01:00");
calendar = XmlUtilities.toXML(context, t);
- assertEquals("2009-01-01T06:00:00.000+01:00", calendar.toString());
+ assertEquals("2009-01-01T06:00:00+01:00", calendar.toString());
assertEquals(t, XmlUtilities.toTemporal(context, calendar));
t = LocalDateTime.parse("2009-08-12T06:20:10");
calendar = XmlUtilities.toXML(context, t);
- assertEquals("2009-08-12T06:20:10.000", calendar.toString());
+ assertEquals("2009-08-12T06:20:10", calendar.toString());
assertEquals(t, XmlUtilities.toTemporal(context, calendar));
t = LocalTime.parse("06:10:45");
calendar = XmlUtilities.toXML(context, t);
- assertEquals("06:10:45.000", calendar.toString());
+ assertEquals("06:10:45", calendar.toString());
assertEquals(t, XmlUtilities.toTemporal(context, calendar));
t = LocalDate.parse("2009-05-08");
diff --git a/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/AbstractLocation.java b/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/AbstractLocation.java
index ac8490e..59a73d2 100644
--- a/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/AbstractLocation.java
+++ b/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/AbstractLocation.java
@@ -22,7 +22,7 @@
import org.opengis.metadata.extent.GeographicExtent;
import org.opengis.metadata.extent.GeographicBoundingBox;
import org.opengis.geometry.Envelope;
-import org.opengis.geometry.coordinate.Position;
+import org.opengis.geometry.DirectPosition;
import org.opengis.util.InternationalString;
import org.apache.sis.util.iso.Types;
import org.apache.sis.geometry.Envelope2D;
@@ -196,13 +196,13 @@
*
* @return coordinates of a representative point for the location instance, or {@code null} if none.
*/
- public Position getPosition() {
+ public DirectPosition getPosition() {
final Envelope envelope = getEnvelope();
if (envelope == null) {
return null;
}
final int dimension = envelope.getDimension();
- final GeneralDirectPosition pos = new GeneralDirectPosition(dimension);
+ final var pos = new GeneralDirectPosition(dimension);
pos.setCoordinateReferenceSystem(envelope.getCoordinateReferenceSystem());
for (int i=0; i<dimension; i++) {
pos.setCoordinate(i, envelope.getMedian(i));
diff --git a/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/LocationFormat.java b/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/LocationFormat.java
index 6b41fd7..34494b1 100644
--- a/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/LocationFormat.java
+++ b/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/LocationFormat.java
@@ -27,6 +27,7 @@
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
+import java.time.Instant;
import javax.measure.Unit;
import org.opengis.util.FactoryException;
import org.opengis.util.InternationalString;
@@ -38,7 +39,6 @@
import org.opengis.metadata.extent.Extent;
import org.opengis.geometry.Envelope;
import org.opengis.geometry.DirectPosition;
-import org.opengis.geometry.coordinate.Position;
import org.apache.sis.io.TabularFormat;
import org.apache.sis.io.TableAppender;
import org.apache.sis.measure.UnitFormat;
@@ -171,13 +171,6 @@
}
/**
- * Returns the direct position for the given position, or {@code null} if none.
- */
- private static DirectPosition position(final Position p) {
- return (p != null) ? p.getDirectPosition() : null;
- }
-
- /**
* Returns a localized version of the given international string, or {@code null} if none.
*/
private static String toString(final InternationalString i18n, final Locale locale) {
@@ -187,8 +180,8 @@
/**
* Returns a localized version of the given date, or {@code null} if none.
*/
- private String toString(final Date date) {
- return (date != null) ? getFormat(Date.class).format(date) : null;
+ private String toString(final Instant date) {
+ return (date != null) ? getFormat(Date.class).format(Date.from(date)) : null;
}
/**
@@ -245,14 +238,14 @@
* the axis order of the geographic bounding box.
*/
final Extent extent = new DefaultExtent(null, location.getGeographicExtent(), null, location.getTemporalExtent());
- final Range<Date> time = Extents.getTimeRange(extent);
+ final Range<Instant> time = Extents.getTimeRange(extent, null).orElse(null);
if (time != null) {
append(table, vocabulary, Vocabulary.Keys.StartDate, toString(time.getMinValue()));
append(table, vocabulary, Vocabulary.Keys.EndDate, toString(time.getMaxValue()));
}
GeographicBoundingBox bbox = Extents.getGeographicBoundingBox(extent);
Envelope envelope = location.getEnvelope();
- DirectPosition position = position(location.getPosition());
+ DirectPosition position = location.getPosition();
DirectPosition geopos = null; // Position in geographic CRS.
CoordinateReferenceSystem crs = null; // Envelope Coordinate Reference System.
CoordinateReferenceSystem normCRS = null; // CRS in conventional (x,y) axis order.
diff --git a/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java b/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
index c38a074..38a0e75 100644
--- a/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
+++ b/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
@@ -2217,7 +2217,7 @@
if (!isValid) {
final String gzd;
try {
- gzd = owner.encoder(crs).encode(owner, getDirectPosition(), true, "", 0, 0);
+ gzd = owner.encoder(crs).encode(owner, this, true, "", 0, 0);
} catch (IllegalArgumentException | FactoryException e) {
throw new GazetteerException(e.getLocalizedMessage(), e);
}
diff --git a/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/SimpleLocation.java b/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/SimpleLocation.java
index 19b6138..4672c25 100644
--- a/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/SimpleLocation.java
+++ b/endorsed/src/org.apache.sis.referencing.gazetteer/main/org/apache/sis/referencing/gazetteer/SimpleLocation.java
@@ -18,7 +18,6 @@
import org.opengis.geometry.Envelope;
import org.opengis.geometry.DirectPosition;
-import org.opengis.geometry.coordinate.Position;
import org.opengis.metadata.extent.GeographicExtent;
import org.opengis.metadata.extent.GeographicBoundingBox;
import org.opengis.referencing.operation.MathTransform;
@@ -114,7 +113,7 @@
* In this simple implementation, this instance is its own centroid coordinate.
*/
@Override
- public final Position getPosition() {
+ public final DirectPosition getPosition() {
return this;
}
diff --git a/endorsed/src/org.apache.sis.referencing.gazetteer/test/org/apache/sis/referencing/gazetteer/GeohashReferenceSystemTest.java b/endorsed/src/org.apache.sis.referencing.gazetteer/test/org/apache/sis/referencing/gazetteer/GeohashReferenceSystemTest.java
index 758af9a..e22fd23 100644
--- a/endorsed/src/org.apache.sis.referencing.gazetteer/test/org/apache/sis/referencing/gazetteer/GeohashReferenceSystemTest.java
+++ b/endorsed/src/org.apache.sis.referencing.gazetteer/test/org/apache/sis/referencing/gazetteer/GeohashReferenceSystemTest.java
@@ -250,7 +250,7 @@
private void testDecode(final GeohashReferenceSystem.Coder coder, final int λi, final int φi) throws TransformException {
for (final Place place : PLACES) {
final AbstractLocation location = coder.decode(place.geohash);
- final DirectPosition result = location.getPosition().getDirectPosition();
+ final DirectPosition result = location.getPosition();
assertEquals(place.longitude, result.getOrdinate(λi), TOLERANCE, place.name);
assertEquals(place.latitude, result.getOrdinate(φi), TOLERANCE, place.name);
}
diff --git a/endorsed/src/org.apache.sis.referencing.gazetteer/test/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java b/endorsed/src/org.apache.sis.referencing.gazetteer/test/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
index 2360999..50b3000 100644
--- a/endorsed/src/org.apache.sis.referencing.gazetteer/test/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
+++ b/endorsed/src/org.apache.sis.referencing.gazetteer/test/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
@@ -214,7 +214,7 @@
{
final AbstractLocation loc = coder.decode(reference);
final Envelope2D envelope = new Envelope2D(loc.getEnvelope());
- final DirectPosition2D pos = new DirectPosition2D(loc.getPosition().getDirectPosition());
+ final DirectPosition2D pos = new DirectPosition2D(loc.getPosition());
assertTrue(envelope.contains(pos), reference);
return pos;
}
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/geometry/CoordinateFormat.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/geometry/CoordinateFormat.java
index 9c2e2e1..ade1c28 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/geometry/CoordinateFormat.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/geometry/CoordinateFormat.java
@@ -35,6 +35,8 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.UncheckedIOException;
+import java.time.Duration;
+import java.time.Instant;
import javax.measure.Unit;
import javax.measure.UnitConverter;
import javax.measure.Quantity;
@@ -57,6 +59,8 @@
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.Characters;
import org.apache.sis.util.privy.LocalizedParseException;
+import org.apache.sis.util.privy.TemporalDate;
+import org.apache.sis.util.privy.Constants;
import org.apache.sis.util.privy.Numerics;
import org.apache.sis.math.DecimalFunctions;
import org.apache.sis.math.MathFunctions;
@@ -71,6 +75,7 @@
import org.apache.sis.measure.QuantityFormat;
import org.apache.sis.measure.UnitFormat;
import org.apache.sis.io.CompoundFormat;
+import org.apache.sis.pending.jdk.JDK23;
/**
@@ -408,12 +413,12 @@
private transient long negate;
/**
- * The time epochs. Non-null only if the at least on coordinate is to be formatted as a date.
+ * The time epochs. Non-null only if at least one coordinate is to be formatted as a date.
*
* <p>This array is created by {@link #createFormats(CoordinateReferenceSystem)}, which is invoked before
* parsing or formatting in a different CRS than last operation, and stay unmodified after creation.</p>
*/
- private transient long[] epochs;
+ private transient Instant[] epochs;
/**
* Dummy field position.
@@ -571,12 +576,12 @@
final CoordinateReferenceSystem t = CRS.getComponentAt(crs, i, i+1);
if (t instanceof TemporalCRS) {
if (epochs == null) {
- epochs = new long[dimension];
+ epochs = new Instant[dimension];
}
types [i] = DATE;
formats[i] = getFormat(Date.class);
- epochs [i] = ((TemporalCRS) t).getDatum().getOrigin().getTime();
- setConverter(dimension, i, unit.asType(Time.class).getConverterTo(Units.MILLISECOND));
+ epochs [i] = TemporalDate.toInstant(((TemporalCRS) t).getDatum().getOrigin());
+ setConverter(dimension, i, unit.asType(Time.class).getConverterTo(Units.SECOND));
if (direction == AxisDirection.PAST) {
negate(i);
}
@@ -1486,7 +1491,7 @@
case ANGLE: valueObject = new Angle (value); break;
case DATE: {
if (Double.isFinite(value)) {
- valueObject = new Date(Math.addExact(Math.round(value), epochs[i]));
+ valueObject = TemporalDate.toDate(TemporalDate.addSeconds(epochs[i], value));
} else {
if (i != 0) toAppendTo.append(separator);
toAppendTo.append(String.valueOf(value));
@@ -1666,7 +1671,8 @@
if (object instanceof Angle) {
value = ((Angle) object).degrees();
} else if (object instanceof Date) {
- value = Math.subtractExact(((Date) object).getTime(), epochs[i]);
+ final Duration d = JDK23.until(epochs[i], ((Date) object).toInstant());
+ value = d.getSeconds() + (d.getNano() / (double) Constants.NANOS_PER_SECOND);
} else {
value = ((Number) object).doubleValue();
}
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Element.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Element.java
index ff07101..d572f2d 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Element.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Element.java
@@ -22,6 +22,7 @@
import java.util.LinkedList;
import java.util.Iterator;
import java.util.Locale;
+import java.time.Instant;
import java.text.ParsePosition;
import java.text.ParseException;
import org.opengis.referencing.cs.CoordinateSystem;
@@ -552,13 +553,13 @@
* @return the next {@link Date} among the children.
* @throws ParseException if no more date is available.
*/
- public Date pullDate(final String key) throws ParseException {
+ public Instant pullDate(final String key) throws ParseException {
final Iterator<Object> iterator = children.iterator();
while (iterator.hasNext()) {
final Object object = iterator.next();
if (object instanceof Date) {
iterator.remove();
- return (Date) object;
+ return ((Date) object).toInstant();
}
}
throw missingComponent(key);
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java
index 55c7bff..949957a 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java
@@ -27,6 +27,8 @@
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.FieldPosition;
+import java.time.Instant;
+import java.time.temporal.Temporal;
import java.io.IOException;
import java.lang.reflect.Array;
import java.math.RoundingMode;
@@ -50,11 +52,10 @@
import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.referencing.operation.ConcatenatedOperation;
import org.opengis.referencing.operation.MathTransform;
+import org.opengis.geometry.DirectPosition;
import org.opengis.geometry.Envelope;
-import org.opengis.geometry.coordinate.Position;
import org.apache.sis.measure.Units;
import org.apache.sis.measure.UnitFormat;
-import org.apache.sis.measure.Range;
import org.apache.sis.measure.MeasurementRange;
import org.apache.sis.math.DecimalFunctions;
import org.apache.sis.math.Vector;
@@ -925,7 +926,7 @@
appendOnNewLine(WKTKeywords.Area, area.getDescription(), ElementKind.EXTENT);
append(Extents.getGeographicBoundingBox(area), BBOX_ACCURACY);
appendVerticalExtent(Extents.getVerticalRange(area));
- appendTemporalExtent(Extents.getTimeRange(area));
+ appendTemporalExtent(area);
}
}
@@ -1005,10 +1006,10 @@
* <li>“{@code TemporalExtent[1980-04-12T18:00:00.0Z, 1980-04-12T21:00:00.0Z]}”</li>
* </ul>
*/
- private void appendTemporalExtent(final Range<Date> range) {
- if (range != null) {
- final Date min = range.getMinValue();
- final Date max = range.getMaxValue();
+ private void appendTemporalExtent(final Extent area) {
+ Extents.getTimeRange(area, null).ifPresent((range) -> {
+ final Instant min = range.getMinValue();
+ final Instant max = range.getMaxValue();
if (min != null && max != null) {
openElement(true, WKTKeywords.TimeExtent);
setColor(ElementKind.EXTENT);
@@ -1017,7 +1018,7 @@
resetColor();
closeElement(true);
}
- }
+ });
}
/**
@@ -1182,11 +1183,35 @@
}
/**
+ * Appends a temporal object (usually an instant).
+ * The {@linkplain Symbols#getSeparator() element separator} will be written before the date if needed.
+ *
+ * @param date the date to append to the WKT, or {@code null} if none.
+ *
+ * @since 1.5
+ */
+ public void append(final Temporal date) {
+ if (date != null) {
+ appendSeparator();
+ if (date instanceof Instant) {
+ // This is the usual case.
+ dateFormat.format(Date.from((Instant) date), buffer, dummy);
+ } else {
+ // Preserve the data structure (e.g. whether there is hours or not, timezone or not).
+ buffer.append(date);
+ }
+ }
+ }
+
+ /**
* Appends a date.
* The {@linkplain Symbols#getSeparator() element separator} will be written before the date if needed.
*
* @param date the date to append to the WKT, or {@code null} if none.
+ *
+ * @deprecated Replaced by {@link #append(Temporal)}.
*/
+ @Deprecated(since="1.5", forRemoval=true)
public void append(final Date date) {
if (date != null) {
appendSeparator();
@@ -1195,10 +1220,10 @@
}
/**
- * Appends a boolean value.
+ * Appends a Boolean value.
* The {@linkplain Symbols#getSeparator() element separator} will be written before the boolean if needed.
*
- * @param value the boolean to append to the WKT.
+ * @param value the Boolean to append to the WKT.
*/
public void append(final boolean value) {
appendSeparator();
@@ -1572,6 +1597,7 @@
}
else if (value instanceof CodeList<?>) append((CodeList<?>) value);
else if (value instanceof Date) append((Date) value);
+ else if (value instanceof Temporal) append((Temporal) value);
else if (value instanceof Boolean) append((Boolean) value);
else if (value instanceof CharSequence) {
append((value instanceof InternationalString) ?
@@ -1632,9 +1658,9 @@
} else if (value instanceof VerticalExtent) {
appendVerticalExtent(Extents.getVerticalRange(new SimpleExtent(null, (VerticalExtent) value, null)));
} else if (value instanceof TemporalExtent) {
- appendTemporalExtent(Extents.getTimeRange(new SimpleExtent(null, null, (TemporalExtent) value)));
- } else if (value instanceof Position) {
- append(AbstractDirectPosition.castOrCopy(((Position) value).getDirectPosition()));
+ appendTemporalExtent(new SimpleExtent(null, null, (TemporalExtent) value));
+ } else if (value instanceof DirectPosition) {
+ append(AbstractDirectPosition.castOrCopy((DirectPosition) value));
} else if (value instanceof Envelope) {
append(AbstractEnvelope.castOrCopy((Envelope) value)); // Non-standard
} else {
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java
index ddd4ca6..30ab63b 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java
@@ -26,13 +26,13 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
-import java.util.Date;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.text.ParseException;
+import java.time.Instant;
import static java.util.Collections.singletonMap;
import javax.measure.Unit;
import javax.measure.Quantity;
@@ -89,6 +89,7 @@
// Specific to the main branch:
import org.opengis.referencing.ReferenceSystem;
+import org.apache.sis.util.privy.TemporalDate;
import org.apache.sis.referencing.internal.ServicesForMetadata;
import org.apache.sis.referencing.factory.GeodeticObjectFactory;
@@ -542,8 +543,8 @@
element.close(ignoredElements);
warning(parent, element, Errors.formatInternational(Errors.Keys.UnsupportedType_1, "TimeExtent[String,String]"), null);
} else {
- final Date startTime = element.pullDate("startTime");
- final Date endTime = element.pullDate("endTime");
+ final Instant startTime = element.pullDate("startTime");
+ final Instant endTime = element.pullDate("endTime");
element.close(ignoredElements);
final DefaultTemporalExtent t = new DefaultTemporalExtent();
t.setBounds(startTime, endTime);
@@ -1495,11 +1496,11 @@
}
final String name = element.pullString ("name");
final Element origin = element.pullElement(MANDATORY, WKTKeywords.TimeOrigin);
- final Date epoch = origin .pullDate("origin");
+ final Instant epoch = origin .pullDate("origin");
origin.close(ignoredElements);
final DatumFactory datumFactory = factories.getDatumFactory();
try {
- return datumFactory.createTemporalDatum(parseAnchorAndClose(element, name), epoch);
+ return datumFactory.createTemporalDatum(parseAnchorAndClose(element, name), TemporalDate.toDate(epoch));
} catch (FactoryException exception) {
throw element.parseFailed(exception);
}
@@ -2056,9 +2057,9 @@
* A ParametricCRS can be either a "normal" one (with a non-null datum), or a DerivedCRS of kind ParametricCRS.
* In the latter case, the datum is null and we have instead DerivingConversion element from a BaseParametricCRS.
*/
- Datum datum = null;
- SingleCRS baseCRS = null;
- Conversion fromBase = null;
+ Datum datum = null;
+ SingleCRS baseCRS = null;
+ Conversion fromBase = null;
if (!isBaseCRS) {
/*
* UNIT[…] in DerivedCRS parameters are mandatory according ISO 19162 and the specification does not said
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java
index 1949a46..01a1e8d 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java
@@ -1066,7 +1066,7 @@
* {@link org.opengis.metadata.extent.VerticalExtent},
* {@link org.opengis.metadata.extent.TemporalExtent},
* {@link org.opengis.geometry.Envelope},
- * {@link org.opengis.geometry.coordinate.Position}
+ * {@link org.opengis.geometry.DirectPosition}
* and {@link Unit}.
*
* @param object the object to format.
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
index 45db156..62c37c6 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
@@ -84,7 +84,7 @@
import org.apache.sis.math.MathFunctions;
import org.apache.sis.measure.Latitude;
import org.apache.sis.measure.Units;
-import static org.apache.sis.util.privy.StandardDateFormat.MILLISECONDS_PER_DAY;
+import static org.apache.sis.util.privy.Constants.SECONDS_PER_DAY;
// Specific to the main branch:
import org.opengis.referencing.crs.GeocentricCRS;
@@ -1557,13 +1557,13 @@
* the legacy date/time formatting classes in the {@link java.text} package uses the proleptic
* Julian calendar for dates before October 15, 1582, while the new date/time formatting classes
* in the {@link java.time.format} package use the ISO-8601 calendar system, which is equivalent
- * to the proleptic Gregorian calendar for every dates. For parsing and formatting of Julian days,
- * the {@link java.text.SimpleDateFormat} class is closer to the common practice (but not ISO 8601
- * compliant).</p>
+ * to the proleptic <em>Gregorian</em> calendar for every dates. For parsing and formatting of
+ * Julian days, the {@link java.text.SimpleDateFormat} class is closer to the common practice
+ * (but not ISO 8601 compliant).</p>
*
* @see <a href="https://en.wikipedia.org/wiki/Julian_day">Julian day on Wikipedia</a>
*/
- JULIAN(Vocabulary.Keys.Julian, -2440588L * MILLISECONDS_PER_DAY + MILLISECONDS_PER_DAY/2,
+ JULIAN(Vocabulary.Keys.Julian, -2440588L * SECONDS_PER_DAY + SECONDS_PER_DAY/2,
"JulianDate", true),
/**
@@ -1574,7 +1574,7 @@
*
* @see <a href="https://en.wikipedia.org/wiki/Julian_day">Julian day on Wikipedia</a>
*/
- MODIFIED_JULIAN(Vocabulary.Keys.ModifiedJulian, -40587L * MILLISECONDS_PER_DAY,
+ MODIFIED_JULIAN(Vocabulary.Keys.ModifiedJulian, -40587L * SECONDS_PER_DAY,
"ModifiedJulianDate", false),
/**
@@ -1586,7 +1586,7 @@
*
* @see <a href="https://en.wikipedia.org/wiki/Julian_day">Julian day on Wikipedia</a>
*/
- TRUNCATED_JULIAN(Vocabulary.Keys.TruncatedJulian, -587L * MILLISECONDS_PER_DAY,
+ TRUNCATED_JULIAN(Vocabulary.Keys.TruncatedJulian, -587L * SECONDS_PER_DAY,
"TruncatedJulianDate", true),
/**
@@ -1597,7 +1597,7 @@
*
* @see <a href="https://en.wikipedia.org/wiki/Julian_day">Julian day on Wikipedia</a>
*/
- DUBLIN_JULIAN(Vocabulary.Keys.DublinJulian, -25568L * MILLISECONDS_PER_DAY + MILLISECONDS_PER_DAY/2,
+ DUBLIN_JULIAN(Vocabulary.Keys.DublinJulian, -25568L * SECONDS_PER_DAY + SECONDS_PER_DAY/2,
"DublinJulian", false),
/**
@@ -1615,7 +1615,7 @@
*
* @since 1.5
*/
- TROPICAL_YEAR(Vocabulary.Keys.TropicalYear, 946684800000L, "TropicalYear", false),
+ TROPICAL_YEAR(Vocabulary.Keys.TropicalYear, 946684800L, "TropicalYear", false),
/**
* Time measured as seconds since January 1st, 1970 at 00:00 UTC.
@@ -1633,7 +1633,7 @@
private final short key;
/**
- * The date and time origin of this temporal datum.
+ * The date and time origin of this temporal datum in seconds since January 1st, 1970 at 00:00 UTC.
*/
private final long epoch;
@@ -1727,8 +1727,8 @@
*/
@OptionalCandidate
public static Temporal forEpoch(final Instant epoch) {
- if (epoch != null) {
- final long e = epoch.toEpochMilli();
+ if (epoch != null && epoch.getNano() == 0) {
+ final long e = epoch.getEpochSecond();
for (final Temporal candidate : values()) {
if (candidate.epoch == e) {
return candidate;
@@ -1847,7 +1847,7 @@
} else {
properties = properties(key);
}
- object = new DefaultTemporalDatum(properties, new Date(epoch));
+ object = new DefaultTemporalDatum(properties, Instant.ofEpochSecond(epoch));
cached = object;
}
}
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/GeodesicsOnEllipsoid.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/GeodesicsOnEllipsoid.java
index f131d5b..206a848 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/GeodesicsOnEllipsoid.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/GeodesicsOnEllipsoid.java
@@ -17,7 +17,7 @@
package org.apache.sis.referencing;
import static java.lang.Math.*;
-import org.opengis.geometry.coordinate.Position;
+import org.opengis.geometry.DirectPosition;
import org.opengis.referencing.datum.Ellipsoid;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.referencing.internal.Resources;
@@ -209,7 +209,7 @@
/**
* Constructs a new geodetic calculator expecting coordinates in the supplied CRS.
*
- * @param crs the referencing system for the {@link Position} arguments and return values.
+ * @param crs the referencing system for the {@link DirectPosition} arguments and return values.
* @param ellipsoid ellipsoid associated to the geodetic component of given CRS.
*/
GeodesicsOnEllipsoid(final CoordinateReferenceSystem crs, final Ellipsoid ellipsoid) {
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/GeodeticCalculator.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/GeodeticCalculator.java
index 9b7c01e..a490213 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/GeodeticCalculator.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/GeodeticCalculator.java
@@ -35,7 +35,6 @@
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.geometry.DirectPosition;
-import org.opengis.geometry.coordinate.Position;
import org.apache.sis.measure.AngleFormat;
import org.apache.sis.measure.Latitude;
import org.apache.sis.measure.Units;
@@ -70,11 +69,11 @@
*
* <p>This class uses the following information:</p>
* <ul>
- * <li>The {@linkplain #setStartPoint(Position) start point}, which is always considered valid after the first call
+ * <li>The {@linkplain #setStartPoint(DirectPosition) start point}, which is always considered valid after the first call
* to {@code setStartPoint(…)}. Its value can only be changed by another call to {@code setStartPoint(…)}.</li>
* <li>One of the followings (the latest specified properties override other properties and determines what will be calculated):
* <ul>
- * <li>the {@linkplain #setEndPoint(Position) end point}, or</li>
+ * <li>the {@linkplain #setEndPoint(DirectPosition) end point}, or</li>
* <li>the {@linkplain #setStartingAzimuth(double) azimuth at start point} together with
* the {@linkplain #setGeodesicDistance(double) geodesic distance} from that point.</li>
* </ul>
@@ -153,7 +152,7 @@
*
* <ul>
* <li>{@link PositionTransformer#defaultCRS} is the default CRS for all methods receiving a
- * {@link Position} argument if the given position does not specify its own CRS.</li>
+ * {@link DirectPosition} argument if the given position does not specify its own CRS.</li>
* <li>{@link PositionTransformer#getCoordinateReferenceSystem()} is the CRS of all methods
* receiving (φ,λ) arguments as {@code double} values.</li>
* </ul>
@@ -269,7 +268,7 @@
* <p>This class is currently not designed for sub-classing outside this package. If in a future version we want to
* relax this restriction, we should revisit the package-private API in order to commit to a safer protected API.</p>
*
- * @param crs the reference system for the {@link Position} arguments and return values.
+ * @param crs the reference system for the {@link DirectPosition} arguments and return values.
* @param ellipsoid ellipsoid associated to the geodetic component of given CRS.
*/
GeodeticCalculator(final CoordinateReferenceSystem crs, final Ellipsoid ellipsoid) {
@@ -285,11 +284,11 @@
/**
* Constructs a new geodetic calculator expecting coordinates in the supplied CRS.
- * All {@code GeodeticCalculator} methods having a {@link Position} argument
+ * All {@code GeodeticCalculator} methods having a {@link DirectPosition} argument
* or return value will use that specified CRS.
* That CRS is the value returned by {@link #getPositionCRS()}.
*
- * @param crs the reference system for the {@link Position} objects.
+ * @param crs the reference system for the {@link DirectPosition} objects.
* @return a new geodetic calculator using the specified CRS.
*/
public static GeodeticCalculator create(final CoordinateReferenceSystem crs) {
@@ -320,13 +319,14 @@
}
/**
- * Returns the Coordinate Reference System (CRS) in which {@code Position}s are represented, unless otherwise specified.
- * This is the CRS of all {@link Position} instances returned by methods in this class. This is also the default CRS
- * assumed by methods receiving a {@link Position} argument when the given position does not specify its CRS.
+ * Returns the Coordinate Reference System (CRS) in which positions are represented, unless otherwise specified.
+ * This is the CRS of all {@link DirectPosition} instances returned by methods in this class.
+ * This is also the default CRS assumed by methods receiving a {@link DirectPosition} argument
+ * when the given position does not specify its CRS.
* This default CRS is specified at construction time.
* It is not necessarily geographic; it may be projected or geocentric.
*
- * @return the default CRS for {@link Position} instances.
+ * @return the default CRS for {@link DirectPosition} instances.
*/
public CoordinateReferenceSystem getPositionCRS() {
return userToGeodetic.defaultCRS;
@@ -400,12 +400,12 @@
* @param point the starting point in any coordinate reference system.
* @throws IllegalArgumentException if the given coordinates cannot be transformed.
*
- * @see #setEndPoint(Position)
+ * @see #setEndPoint(DirectPosition)
*/
- public void setStartPoint(final Position point) {
+ public void setStartPoint(final DirectPosition point) {
final DirectPosition p;
try {
- p = userToGeodetic.transform(point.getDirectPosition());
+ p = userToGeodetic.transform(point);
} catch (TransformException e) {
throw new IllegalArgumentException(transformError(false), e);
}
@@ -435,7 +435,7 @@
/**
* Returns or computes the destination in the CRS specified at construction time. This method returns
- * the point specified in the last call to a {@link #setEndPoint(Position) setEndPoint(…)} method,
+ * the point specified in the last call to a {@link #setEndPoint(DirectPosition) setEndPoint(…)} method,
* unless the {@linkplain #setStartingAzimuth(double) starting azimuth} and
* {@linkplain #setGeodesicDistance(double) geodesic distance} have been set more recently.
* In the latter case, the end point will be computed from the {@linkplain #getStartPoint() start point}
@@ -467,12 +467,12 @@
* @param position the destination (end point) in any coordinate reference system.
* @throws IllegalArgumentException if the given coordinates cannot be transformed.
*
- * @see #setStartPoint(Position)
+ * @see #setStartPoint(DirectPosition)
*/
- public void setEndPoint(final Position position) {
+ public void setEndPoint(final DirectPosition position) {
final DirectPosition p;
try {
- p = userToGeodetic.transform(position.getDirectPosition());
+ p = userToGeodetic.transform(position);
} catch (TransformException e) {
throw new IllegalArgumentException(transformError(false), e);
}
@@ -504,7 +504,7 @@
* Returns or computes the angular heading at the starting point of a geodesic path.
* Azimuth is relative to geographic North with values increasing clockwise.
* This method returns the azimuth normalized to [-180 … +180]° range given in last call to
- * {@link #setStartingAzimuth(double)} method, unless the {@link #setEndPoint(Position) setEndPoint(…)}
+ * {@link #setStartingAzimuth(double)} method, unless the {@link #setEndPoint(DirectPosition) setEndPoint(…)}
* method has been invoked more recently. In the latter case, the azimuth will be computed from the
* {@linkplain #getStartPoint() start point} and the current end point.
*
@@ -541,8 +541,9 @@
/**
* Computes the angular heading at the ending point of a geodesic path.
- * Azimuth is relative to geographic North with values increasing clockwise. This method computes the azimuth
- * from the current {@linkplain #setStartPoint(Position) start point} and {@linkplain #setEndPoint(Position) end point},
+ * Azimuth is relative to geographic North with values increasing clockwise.
+ * This method computes the azimuth from the current {@linkplain #setStartPoint(DirectPosition) start point}
+ * and {@linkplain #setEndPoint(DirectPosition) end point},
* or from start point and the current {@linkplain #setStartingAzimuth(double) starting azimuth} and
* {@linkplain #setGeodesicDistance(double) geodesic distance}.
*
@@ -579,8 +580,9 @@
/**
* Returns or computes the shortest distance from start point to end point. This is sometimes called "great circle"
* or "orthodromic" distance. This method returns the value given in last call to {@link #setGeodesicDistance(double)},
- * unless the {@link #setEndPoint(Position) setEndPoint(…)} method has been invoked more recently. In the latter case,
- * the distance will be computed from the {@linkplain #getStartPoint() start point} and current end point.
+ * unless the {@link #setEndPoint(DirectPosition) setEndPoint(…)} method has been invoked more recently.
+ * In the latter case, the distance will be computed from the {@linkplain #getStartPoint() start point}
+ * and current end point.
*
* @return the shortest distance in the unit of measurement given by {@link #getDistanceUnit()}.
* @throws IllegalStateException if the start point or end point has not been set.
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultTemporalCRS.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultTemporalCRS.java
index 6f95f9b..b9c9390 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultTemporalCRS.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultTemporalCRS.java
@@ -21,6 +21,8 @@
import java.util.Objects;
import java.time.Instant;
import java.time.Duration;
+import java.time.temporal.Temporal;
+import java.time.temporal.ChronoField;
import java.io.IOException;
import java.io.ObjectInputStream;
import jakarta.xml.bind.annotation.XmlType;
@@ -40,8 +42,11 @@
import org.apache.sis.io.wkt.Formatter;
import org.apache.sis.measure.Units;
import org.apache.sis.math.Fraction;
-import static org.apache.sis.util.privy.StandardDateFormat.NANOS_PER_SECOND;
-import static org.apache.sis.util.privy.StandardDateFormat.MILLIS_PER_SECOND;
+import static org.apache.sis.util.privy.Constants.NANOS_PER_SECOND;
+import static org.apache.sis.util.privy.Constants.MILLIS_PER_SECOND;
+
+// Specific to the main and geoapi-3.1 branches:
+import org.apache.sis.util.privy.TemporalDate;
/**
@@ -223,16 +228,16 @@
*/
private void initializeConverter() {
toSeconds = getUnit().getConverterTo(Units.SECOND);
- long t = datum.getOrigin().getTime();
- origin = t / MILLIS_PER_SECOND;
- t %= MILLIS_PER_SECOND;
- if (t != 0) {
+ final Temporal t = TemporalDate.toTemporal(datum.getOrigin());
+ origin = t.getLong(ChronoField.INSTANT_SECONDS);
+ int r = t.get(ChronoField.NANO_OF_SECOND);
+ if (r != 0) {
/*
* The origin is usually an integer number of days or hours. It rarely has a fractional number of seconds.
* If it happens anyway, put the fractional number of seconds in the converter instead of adding another
* field in this class for such very rare situation. Accuracy should be okay since the offset is small.
*/
- UnitConverter c = Units.converter(null, Fraction.valueOf(t, MILLIS_PER_SECOND));
+ UnitConverter c = Units.converter(null, new Fraction(r, NANOS_PER_SECOND));
toSeconds = c.concatenate(toSeconds);
}
}
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/BursaWolfParameters.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/BursaWolfParameters.java
index 637b7a0..759856a 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/BursaWolfParameters.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/BursaWolfParameters.java
@@ -16,9 +16,9 @@
*/
package org.apache.sis.referencing.datum;
-import java.util.Date;
import java.util.Arrays;
import java.util.Objects;
+import java.time.temporal.Temporal;
import java.io.Serializable;
import static java.lang.Math.abs;
import org.opengis.metadata.extent.Extent;
@@ -120,7 +120,7 @@
* (case 1 above) over the <i>early-binding</i> approach (case 3 above).
*
* @author Martin Desruisseaux (IRD, Geomatys)
- * @version 1.4
+ * @version 1.5
*
* @see DefaultGeodeticDatum#getBursaWolfParameters()
* @see <a href="https://en.wikipedia.org/wiki/Helmert_transformation">Wikipedia: Helmert transformation</a>
@@ -386,7 +386,7 @@
/**
* Inverts in-place the transformation by inverting the sign of all numerical parameters.
- * The {@linkplain #getPositionVectorTransformation(Date) position vector transformation} matrix
+ * The {@linkplain #getPositionVectorTransformation(Temporal) position vector transformation} matrix
* created from inverted Bursa-Wolf parameters will be <strong>approximately</strong> equals
* to the {@linkplain org.apache.sis.referencing.operation.matrix.MatrixSIS#inverse() inverse}
* of the matrix created from the original parameters. The equality holds approximately only
@@ -406,7 +406,7 @@
*
* @return fractional number of tropical years since reference time, or {@code null}.
*/
- DoubleDouble period(final Date time) {
+ DoubleDouble period(final Temporal time) {
return null;
}
@@ -414,7 +414,7 @@
* Returns the parameter at the given index. If this {@code BursaWolfParameters} is time-dependent,
* then the returned value shall be corrected the time elapsed since the reference time.
*
- * The {@code factor} argument shall be the value computed by {@link #period(Date)},
+ * The {@code factor} argument shall be the value computed by {@link #period(Temporal)},
* multiplied by 1000 for all {@code index} values except 6.
* The 1000 factor is for conversion mm/year to m/year or milli-arc-seconds to arc-seconds.
*
@@ -478,8 +478,10 @@
* @return an affine transform in geocentric space created from this Bursa-Wolf parameters and the given time.
*
* @see DefaultGeodeticDatum#getPositionVectorTransformation(GeodeticDatum, Extent)
+ *
+ * @since 1.5
*/
- public Matrix getPositionVectorTransformation(final Date time) {
+ public Matrix getPositionVectorTransformation(final Temporal time) {
final DoubleDouble period = period(time);
if (period == null && isTranslation()) {
final Matrix4 matrix = new Matrix4();
@@ -524,7 +526,7 @@
* @param tolerance the tolerance error for the skew-symmetric matrix test, in units of PPM or arc-seconds (e.g. 1E-8).
* @throws IllegalArgumentException if the specified matrix does not met the conditions.
*
- * @see #getPositionVectorTransformation(Date)
+ * @see #getPositionVectorTransformation(Temporal)
*/
public void setPositionVectorTransformation(final Matrix matrix, final double tolerance) throws IllegalArgumentException {
final int numRow = matrix.getNumRow();
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
index 1ec57ec..9dc62de 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
@@ -18,7 +18,6 @@
import java.util.Map;
import java.util.Arrays;
-import java.util.Date;
import java.util.Objects;
import java.util.logging.Logger;
import java.time.Instant;
@@ -413,7 +412,7 @@
* @param areaOfInterest the geographic and temporal extent where the transformation should be valid, or {@code null}.
* @return an affine transform from {@code this} to {@code target} in geocentric space, or {@code null} if none.
*
- * @see BursaWolfParameters#getPositionVectorTransformation(Date)
+ * @see BursaWolfParameters#getPositionVectorTransformation(Temporal)
*/
public Matrix getPositionVectorTransformation(final GeodeticDatum targetDatum, final Extent areaOfInterest) {
ensureNonNull("targetDatum", targetDatum);
@@ -432,7 +431,7 @@
return Matrices.inverse(createTransformation(candidate, areaOfInterest));
} catch (NoninvertibleMatrixException e) {
/*
- * Should never happen because BursaWolfParameters.getPositionVectorTransformation(Date)
+ * Should never happen because BursaWolfParameters.getPositionVectorTransformation(Temporal)
* is defined in such a way that matrix should always be invertible. If it happen anyway,
* returning `null` is allowed by this method's contract.
*/
@@ -483,7 +482,7 @@
}
/**
- * Invokes {@link BursaWolfParameters#getPositionVectorTransformation(Date)} for a date calculated from
+ * Invokes {@link BursaWolfParameters#getPositionVectorTransformation(Temporal)} for a date calculated from
* the temporal elements on the given extent. This method chooses an instant located midway between the
* start and end time.
*/
@@ -493,7 +492,8 @@
* not a subclass of BursaWolfParameters. This optimisation covers the vast majority of cases.
*/
return bursaWolf.getPositionVectorTransformation(bursaWolf.getClass() != BursaWolfParameters.class ?
- Extents.getDate(areaOfInterest, 0.5) : null); // 0.5 is for choosing midway instant.
+ Extents.getInstant(areaOfInterest, null, 0.5).orElse(null) : null);
+ // 0.5 is for choosing the instant midway between start and end.
}
/**
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultTemporalDatum.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultTemporalDatum.java
index f7aade2..5f95872 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultTemporalDatum.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultTemporalDatum.java
@@ -19,6 +19,7 @@
import java.util.Date;
import java.util.Map;
import java.util.Objects;
+import java.time.temporal.Temporal;
import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.XmlSchemaType;
import jakarta.xml.bind.annotation.XmlElement;
@@ -28,8 +29,7 @@
import org.opengis.util.InternationalString;
import org.opengis.referencing.datum.TemporalDatum;
import org.apache.sis.referencing.privy.WKTKeywords;
-import org.apache.sis.xml.bind.gml.UniversalTimeAdapter;
-import org.apache.sis.metadata.privy.ImplementationHelper;
+import org.apache.sis.xml.bind.gml.TemporalAdapter;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.io.wkt.Formatter;
import org.apache.sis.io.wkt.FormattableObject;
@@ -37,6 +37,9 @@
// Specific to the main branch:
import org.opengis.referencing.ReferenceIdentifier;
+// Specific to the main and geoapi-3.1 branches:
+import org.apache.sis.util.privy.TemporalDate;
+
/**
* Defines the origin of a temporal coordinate reference system.
@@ -70,7 +73,7 @@
* all components were created using only SIS factories and static constants.
*
* @author Martin Desruisseaux (IRD, Geomatys)
- * @version 1.4
+ * @version 1.5
*
* @see org.apache.sis.referencing.CommonCRS.Temporal#datum()
* @see org.apache.sis.referencing.cs.DefaultTimeCS
@@ -85,17 +88,21 @@
/**
* Serial number for inter-operability with different versions.
*/
- private static final long serialVersionUID = 3357241732140076884L;
+ private static final long serialVersionUID = -1507650596130032757L;
/**
- * The date and time origin of this temporal datum, or {@link Long#MIN_VALUE} if none.
- * This information is mandatory, but SIS is tolerant to missing value is case a XML
- * fragment was incomplete.
+ * The date and time origin of this temporal datum, or {@code null} if none.
+ * This information is mandatory, but SIS is tolerant to missing value
+ * is case a XML fragment was incomplete.
*
* <p><b>Consider this field as final!</b>
- * This field is modified only at unmarshalling time by {@link #setOrigin(Date)}</p>
+ * This field is modified only at unmarshalling time.</p>
*/
- private long origin;
+ @SuppressWarnings("serial") // Most implementations are serializable.
+ @XmlSchemaType(name = "dateTime")
+ @XmlElement(name = "origin", required = true)
+ @XmlJavaTypeAdapter(TemporalAdapter.class)
+ private Temporal origin;
/**
* Creates a temporal datum from the given properties. The properties map is given
@@ -143,10 +150,25 @@
* @param origin the date and time origin of this temporal datum.
*
* @see org.apache.sis.referencing.factory.GeodeticObjectFactory#createTemporalDatum(Map, Date)
+ *
+ * @since 1.5
*/
- public DefaultTemporalDatum(final Map<String,?> properties, final Date origin) {
+ public DefaultTemporalDatum(final Map<String,?> properties, final Temporal origin) {
super(properties);
- this.origin = origin.getTime();
+ this.origin = origin;
+ }
+
+ /**
+ * Creates a temporal datum from the given properties.
+ *
+ * @param properties the properties to be given to the identified object.
+ * @param origin the date and time origin of this temporal datum.
+ *
+ * @deprecated Use {@link #DefaultTemporalDatum(Map, Temporal)} instead.
+ */
+ @Deprecated(since="1.5")
+ public DefaultTemporalDatum(final Map<String,?> properties, final Date origin) {
+ this(properties, TemporalDate.toTemporal(origin));
}
/**
@@ -162,7 +184,7 @@
*/
protected DefaultTemporalDatum(final TemporalDatum datum) {
super(datum);
- origin = ImplementationHelper.toMilliseconds(datum.getOrigin());
+ origin = TemporalDate.toTemporal(datum.getOrigin());
}
/**
@@ -202,11 +224,8 @@
* @return the date and time origin of this temporal datum.
*/
@Override
- @XmlSchemaType(name = "dateTime")
- @XmlElement(name = "origin", required = true)
- @XmlJavaTypeAdapter(UniversalTimeAdapter.class)
public Date getOrigin() {
- return ImplementationHelper.toDate(origin);
+ return TemporalDate.toDate(origin);
}
/**
@@ -228,7 +247,7 @@
}
switch (mode) {
case STRICT: {
- return origin == ((DefaultTemporalDatum) object).origin;
+ return Objects.equals(origin, ((DefaultTemporalDatum) object).origin);
}
default: {
return Objects.equals(getOrigin(), ((TemporalDatum) object).getOrigin());
@@ -245,7 +264,7 @@
*/
@Override
protected long computeHashCode() {
- return super.computeHashCode() + origin;
+ return super.computeHashCode() + Objects.hashCode(origin);
}
/**
@@ -261,7 +280,7 @@
@Override
protected String formatTo(final Formatter formatter) {
super.formatTo(formatter);
- formatter.append(new Origin(getOrigin()));
+ formatter.append(new Origin(TemporalDate.toTemporal(getOrigin())));
if (formatter.getConvention().majorVersion() == 1) {
formatter.setInvalidWKT(this, null);
}
@@ -273,10 +292,10 @@
*/
private static final class Origin extends FormattableObject {
/** The value of the origin to format. */
- private final Date origin;
+ private final Temporal origin;
/** Creates a new time origin with the given value. */
- Origin(final Date origin) {
+ Origin(final Temporal origin) {
this.origin = origin;
}
@@ -310,24 +329,10 @@
* reserved to JAXB, which will assign values to the fields using reflection.
*/
private DefaultTemporalDatum() {
- origin = Long.MIN_VALUE;
/*
* The origin is mandatory for SIS working. We do not verify its presence here because the verification
- * would have to be done in an 'afterMarshal(…)' method and throwing an exception in that method causes
+ * would have to be done in an `afterMarshal(…)` method and throwing an exception in that method causes
* the whole unmarshalling to fail. But the CD_TemporalDatum adapter does some verifications.
*/
}
-
- /**
- * Invoked by JAXB only at unmarshalling time.
- *
- * @see #getOrigin()
- */
- private void setOrigin(final Date value) {
- if (origin == Long.MIN_VALUE) {
- origin = value.getTime();
- } else {
- ImplementationHelper.propertyAlreadySet(DefaultTemporalDatum.class, "setOrigin", "origin");
- }
- }
}
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/TimeDependentBWP.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/TimeDependentBWP.java
index f0cfaa9..a92486d 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/TimeDependentBWP.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/TimeDependentBWP.java
@@ -17,12 +17,15 @@
package org.apache.sis.referencing.datum;
import java.util.Date;
+import java.util.Objects;
+import java.time.Duration;
+import java.time.temporal.Temporal;
import org.opengis.metadata.extent.Extent;
import org.opengis.referencing.datum.GeodeticDatum;
import org.opengis.referencing.datum.PrimeMeridian;
import org.apache.sis.util.privy.DoubleDouble;
+import org.apache.sis.util.privy.Constants;
import static org.apache.sis.util.ArgumentChecks.*;
-import static org.apache.sis.referencing.privy.Formulas.JULIAN_YEAR_LENGTH;
/**
@@ -57,7 +60,7 @@
* </ul>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 1.4
+ * @version 1.5
* @since 0.4
*/
@SuppressWarnings("CloneableImplementsClone") // Fields in this class do not need cloning.
@@ -65,7 +68,7 @@
/**
* Serial number for inter-operability with different versions.
*/
- private static final long serialVersionUID = -4628799278259080258L;
+ private static final long serialVersionUID = 8404372938646871943L;
/**
* Rate of change of X-axis translation in millimetres per year (EPSG:1040).
@@ -108,7 +111,8 @@
/**
* The reference epoch for time-dependent parameters (EPSG:1047).
*/
- private final long timeReference;
+ @SuppressWarnings("serial") // Most implementations are serializable.
+ private final Temporal timeReference;
/**
* Creates a new instance for the given target datum, domain of validity and time reference.
@@ -119,10 +123,22 @@
* @param domainOfValidity area or region in which a coordinate transformation based on those Bursa-Wolf parameters
* is valid, or {@code null} if unspecified.
* @param timeReference the reference epoch for time-dependent parameters.
+ *
+ * @since 1.5
*/
- public TimeDependentBWP(final GeodeticDatum targetDatum, final Extent domainOfValidity, final Date timeReference) {
+ public TimeDependentBWP(final GeodeticDatum targetDatum, final Extent domainOfValidity, final Temporal timeReference) {
super(targetDatum, domainOfValidity);
- this.timeReference = timeReference.getTime();
+ this.timeReference = Objects.requireNonNull(timeReference);
+ }
+
+ /**
+ * Creates a new instance for the given target datum, domain of validity and time reference.
+ *
+ * @deprecated Replaced by {@link #TimeDependentBWP(GeodeticDatum, Extent, Temporal)}.
+ */
+ @Deprecated(since="1.5", forRemoval=true)
+ public TimeDependentBWP(final GeodeticDatum targetDatum, final Extent domainOfValidity, final Date timeReference) {
+ this(targetDatum, domainOfValidity, timeReference.toInstant());
}
/**
@@ -144,8 +160,8 @@
*
* @return the reference epoch for time-dependent parameters.
*/
- public Date getTimeReference() {
- return new Date(timeReference);
+ public Temporal getTimeReference() {
+ return timeReference;
}
/**
@@ -155,11 +171,11 @@
* @return fractional number of tropical years since reference time, or {@code null}.
*/
@Override
- final DoubleDouble period(final Date time) {
+ final DoubleDouble period(final Temporal time) {
if (time != null) {
- final long millis = time.getTime() - timeReference;
- if (millis != 0) { // Returns null for 0 as an optimization.
- return DoubleDouble.of(millis).divide(JULIAN_YEAR_LENGTH);
+ final Duration d = Duration.between(timeReference, time);
+ if (!d.isZero()) { // Returns null for 0 as an optimization.
+ return DoubleDouble.of(d).divide(Constants.MILLIS_PER_TROPICAL_YEAR * Constants.NANOS_PER_MILLISECOND);
}
}
return null;
@@ -285,6 +301,6 @@
*/
@Override
public int hashCode() {
- return super.hashCode() ^ Long.hashCode(timeReference);
+ return super.hashCode() ^ timeReference.hashCode();
}
}
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
index 63527e9..dfd35e7 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
@@ -57,7 +57,7 @@
import org.apache.sis.util.logging.PerformanceLevel;
import org.apache.sis.util.collection.Cache;
import org.apache.sis.util.privy.CollectionsExt;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
import org.apache.sis.metadata.simple.SimpleCitation;
import org.apache.sis.system.ReferenceQueueConsumer;
import org.apache.sis.system.DelayedExecutor;
@@ -219,7 +219,7 @@
value = depth;
} else {
text = "%s made available %d seconds ago";
- value = Math.round((System.nanoTime() - timestamp) / (double) StandardDateFormat.NANOS_PER_SECOND);
+ value = Math.round((System.nanoTime() - timestamp) / (double) Constants.NANOS_PER_SECOND);
}
return String.format(text, Classes.getShortClassName(factory), value);
}
@@ -493,7 +493,7 @@
caller = "create".concat(type.getSimpleName());
}
final Level level = PerformanceLevel.forDuration(time, TimeUnit.NANOSECONDS);
- final Double duration = time / (double) StandardDateFormat.NANOS_PER_SECOND;
+ final Double duration = time / (double) Constants.NANOS_PER_SECOND;
final Messages resources = Messages.forLocale(null);
final LogRecord record;
if (code != null) {
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
index 84c406a..f988b0e 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
@@ -1703,6 +1703,8 @@
* @param cs the coordinate system (never null).
* @return the combined CRS, or {@code null} if the given information are not sufficient.
* @throws FactoryException if an error occurred while creating the combined CRS.
+ *
+ * @todo Handle {@link DatumEnsemble}.
*/
private static GeodeticCRS combine(final GeodeticDatum datum, final CoordinateSystem cs) throws FactoryException {
final Map<String,?> properties = IdentifiedObjects.getProperties(datum, Datum.IDENTIFIERS_KEY);
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ReferenceKeeper.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ReferenceKeeper.java
index 63e06fc..25d466f 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ReferenceKeeper.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ReferenceKeeper.java
@@ -20,7 +20,7 @@
import org.apache.sis.system.Configuration;
import org.apache.sis.system.DelayedExecutor;
import org.apache.sis.system.DelayedRunnable;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
/**
@@ -56,7 +56,7 @@
* Time to wait before to remove entries from this map. Current value is 5 minutes.
*/
@Configuration
- private static final long EXPIRATION_TIME = 5L * 60 * StandardDateFormat.NANOS_PER_SECOND;
+ private static final long EXPIRATION_TIME = 5L * 60 * Constants.NANOS_PER_SECOND;
/**
* The objects to retain by strong reference. May contains duplicated values and {@code null} anywhere.
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
index 8cd976b..e64088b 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
@@ -41,10 +41,9 @@
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.sql.SQLException;
-import java.text.DateFormat;
-import java.text.ParseException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.time.temporal.Temporal;
import javax.measure.Unit;
import javax.measure.quantity.Angle;
import javax.measure.quantity.Length;
@@ -118,11 +117,12 @@
import org.apache.sis.measure.NumberRange;
import org.apache.sis.measure.Units;
import org.apache.sis.pending.jdk.JDK16;
+import static org.apache.sis.util.privy.Constants.UTC;
import static org.apache.sis.util.Utilities.equalsIgnoreMetadata;
-import static org.apache.sis.util.privy.StandardDateFormat.UTC;
import static org.apache.sis.referencing.internal.ServicesForMetadata.CONNECTION;
// Specific to the main branch:
+import org.apache.sis.util.privy.TemporalDate;
import org.apache.sis.referencing.internal.ServicesForMetadata;
import org.apache.sis.referencing.cs.DefaultParametricCS;
import org.apache.sis.referencing.datum.DefaultParametricDatum;
@@ -244,12 +244,6 @@
private Calendar calendar;
/**
- * The object to use for parsing dates, created when first needed. This is used for
- * parsing the origin of temporal datum. This is an Apache SIS specific extension.
- */
- private DateFormat dateFormat;
-
- /**
* A pool of prepared statements. Keys are {@link String} objects related to their originating method
* (for example "Ellipsoid" for {@link #createEllipsoid(String)}).
*/
@@ -1722,19 +1716,16 @@
* "date" type would have been better, but we do not modify the EPSG model.
*/
case "temporal": {
- final Date originDate;
+ final Temporal originDate;
if (Strings.isNullOrEmpty(anchor)) {
throw new FactoryDataException(resources().getString(Resources.Keys.DatumOriginShallBeDate));
}
- if (dateFormat == null) {
- dateFormat = new StandardDateFormat(); // Default to UTC timezone.
- }
try {
- originDate = dateFormat.parse(anchor);
- } catch (ParseException e) {
+ originDate = StandardDateFormat.parseBest(anchor);
+ } catch (RuntimeException e) {
throw new FactoryDataException(resources().getString(Resources.Keys.DatumOriginShallBeDate), e);
}
- datum = datumFactory.createTemporalDatum(properties, originDate);
+ datum = datumFactory.createTemporalDatum(properties, TemporalDate.toDate(originDate));
break;
}
/*
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
index d789151..dfd4171 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
@@ -30,7 +30,7 @@
import org.apache.sis.util.Exceptions;
import org.apache.sis.metadata.sql.privy.ScriptRunner;
import org.apache.sis.metadata.sql.privy.SQLUtilities;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
import org.apache.sis.system.Fallback;
import org.apache.sis.util.resources.Messages;
import org.apache.sis.util.logging.PerformanceLevel;
@@ -247,7 +247,7 @@
time = System.nanoTime() - time;
InstallationScriptProvider.log(Messages.forLocale(locale).getLogRecord(
PerformanceLevel.forDuration(time, TimeUnit.NANOSECONDS),
- Messages.Keys.InsertDuration_2, numRows, time / (float) StandardDateFormat.NANOS_PER_SECOND));
+ Messages.Keys.InsertDuration_2, numRows, time / (float) Constants.NANOS_PER_SECOND));
}
/**
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Epoch.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Epoch.java
index 80e0e3f..558fff3 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Epoch.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Epoch.java
@@ -27,7 +27,7 @@
import org.apache.sis.io.wkt.FormattableObject;
import org.apache.sis.math.DecimalFunctions;
import org.apache.sis.referencing.privy.WKTKeywords;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
/**
@@ -70,7 +70,7 @@
fractionDigits = 2;
} else if (epoch.isSupported(ChronoField.NANO_OF_DAY)) {
day = epoch.getLong(ChronoField.NANO_OF_DAY);
- day /= StandardDateFormat.MILLISECONDS_PER_DAY * (long) StandardDateFormat.NANOS_PER_MILLISECOND;
+ day /= (double) Constants.NANOSECONDS_PER_DAY;
fractionDigits = (epoch.get(ChronoField.NANO_OF_SECOND) != 0) ? 16 : 8;
}
day += epoch.get(ChronoField.DAY_OF_YEAR) - 1;
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
index 35f9d4d..b9a1991 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
@@ -22,6 +22,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.ListIterator;
+import java.time.Duration;
import javax.measure.Unit;
import javax.measure.IncommensurableException;
import javax.measure.quantity.Time;
@@ -36,6 +37,10 @@
import org.opengis.metadata.extent.GeographicBoundingBox;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptorGroup;
+import org.apache.sis.parameter.TensorParameters;
+import org.apache.sis.measure.Units;
+import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.metadata.iso.extent.Extents;
import org.apache.sis.referencing.CRS;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.referencing.IdentifiedObjects;
@@ -46,6 +51,12 @@
import org.apache.sis.referencing.privy.ReferencingUtilities;
import org.apache.sis.referencing.internal.AnnotatedMatrix;
import org.apache.sis.referencing.internal.Resources;
+import org.apache.sis.referencing.cs.CoordinateSystems;
+import org.apache.sis.referencing.datum.BursaWolfParameters;
+import org.apache.sis.referencing.datum.DefaultGeodeticDatum;
+import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
import org.apache.sis.referencing.operation.provider.Affine;
import org.apache.sis.referencing.operation.provider.DatumShiftMethod;
import org.apache.sis.referencing.operation.provider.Geographic2Dto3D;
@@ -54,21 +65,14 @@
import org.apache.sis.referencing.operation.provider.GeocentricToGeographic;
import org.apache.sis.referencing.operation.provider.GeocentricAffine;
import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.privy.DoubleDouble;
import org.apache.sis.util.privy.Constants;
-import org.apache.sis.measure.Units;
-import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.metadata.iso.extent.Extents;
-import org.apache.sis.parameter.TensorParameters;
-import org.apache.sis.referencing.cs.CoordinateSystems;
-import org.apache.sis.referencing.datum.BursaWolfParameters;
-import org.apache.sis.referencing.datum.DefaultGeodeticDatum;
-import org.apache.sis.referencing.operation.matrix.Matrices;
-import org.apache.sis.referencing.operation.matrix.MatrixSIS;
-import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
+import org.apache.sis.util.privy.DoubleDouble;
import org.apache.sis.util.resources.Vocabulary;
import static org.apache.sis.util.Utilities.equalsIgnoreMetadata;
+// Specific to the main and geoapi-3.1 branches:
+import org.apache.sis.util.privy.TemporalDate;
+
/**
* Finds a conversion or transformation path from a source CRS to a target CRS.
@@ -859,15 +863,16 @@
final TimeCS sourceCS = sourceCRS.getCoordinateSystem();
final TimeCS targetCS = targetCRS.getCoordinateSystem();
/*
- * Compute the epoch shift. The epoch is the time "0" in a particular coordinate reference system.
- * For example, the epoch for java.util.Date object is january 1, 1970 at 00:00 UTC. We compute how
- * much to add to a time in `sourceCRS` in order to get a time in `targetCRS`.
+ * Compute the epoch shift. The epoch is the "time zero" in a particular coordinate reference system.
+ * For example, the epoch of Java temporal objects (e.g. `Instant`) is january 1, 1970 at 00:00 UTC.
+ * We compute how much to add to a time in `sourceCRS` in order to get a time in `targetCRS`.
* This "epoch shift" is in units of `targetCRS`.
*/
final Unit<Time> targetUnit = targetCS.getAxis(0).getUnit().asType(Time.class);
- DoubleDouble epochShift = DoubleDouble.of(sourceDatum.getOrigin().getTime());
- epochShift = epochShift.subtract(targetDatum.getOrigin().getTime());
- epochShift = DoubleDouble.of(Units.MILLISECOND.getConverterTo(targetUnit).convert(epochShift), true);
+ DoubleDouble epochShift = DoubleDouble.of(Duration.between(
+ TemporalDate.toTemporal(targetDatum.getOrigin()),
+ TemporalDate.toTemporal(sourceDatum.getOrigin())));
+ epochShift = DoubleDouble.of(Units.NANOSECOND.getConverterTo(targetUnit).convert(epochShift), true);
/*
* Check axis directions. The method `swapAndScaleAxes` should returns a matrix of size 2×2.
* The element at index (0,0) may be +1 if source and target axes are in the same direction,
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ExtentSelector.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ExtentSelector.java
index 4b3f423..e5b4e05 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ExtentSelector.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ExtentSelector.java
@@ -16,7 +16,6 @@
*/
package org.apache.sis.referencing.privy;
-import java.util.Date;
import java.time.Instant;
import java.time.Duration;
import org.opengis.metadata.extent.Extent;
@@ -25,6 +24,7 @@
import org.apache.sis.math.MathFunctions;
import org.apache.sis.measure.Range;
import org.apache.sis.util.resources.Errors;
+import org.apache.sis.pending.jdk.JDK23;
/**
@@ -221,12 +221,10 @@
public final boolean setExtentOfInterest(final Extent domain, final GeographicBoundingBox aoi, final Instant[] toi) {
areaOfInterest = Extents.intersection(aoi, Extents.getGeographicBoundingBox(domain));
minTOI = maxTOI = null;
- final Range<Date> tr = Extents.getTimeRange(domain);
- if (tr != null) {
- Date t;
- if ((t = tr.getMinValue()) != null) minTOI = t.toInstant();
- if ((t = tr.getMaxValue()) != null) maxTOI = t.toInstant();
- }
+ Extents.getTimeRange(domain, null).ifPresent((tr) -> {
+ minTOI = tr.getMinValue();
+ maxTOI = tr.getMaxValue();
+ });
if (toi != null && toi.length != 0) {
Instant t = toi[0];
if (minTOI == null || (t != null && t.isAfter(minTOI))) {
@@ -367,7 +365,7 @@
*/
private Duration overtime(final Instant startTime, final Instant endTime, final Duration intersection) {
return (startTime != null && endTime != null && intersection != null)
- ? round(Duration.between(startTime, endTime).minus(intersection)) : null;
+ ? round(JDK23.until(startTime, endTime).minus(intersection)) : null;
}
/**
@@ -379,11 +377,10 @@
* @param object a user object associated to the given extent.
*/
public void evaluate(final Extent domain, final T object) {
- Date t;
- final Range<Date> tr = Extents.getTimeRange(domain);
+ final Range<Instant> tr = Extents.getTimeRange(domain, null).orElse(null);
evaluate(Extents.getGeographicBoundingBox(domain),
- (tr != null && (t = tr.getMinValue()) != null) ? t.toInstant() : null,
- (tr != null && (t = tr.getMaxValue()) != null) ? t.toInstant() : null,
+ (tr != null) ? tr.getMinValue() : null,
+ (tr != null) ? tr.getMaxValue() : null,
object);
}
@@ -409,7 +406,7 @@
if (tmax != null && maxTOI != null && tmax.isAfter (maxTOI)) tmax = maxTOI;
final Duration duration;
if (tmin != null && tmax != null) {
- duration = Duration.between(tmin, tmax);
+ duration = JDK23.until(tmin, tmax);
if (duration.isNegative()) return;
} else {
duration = null;
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/Formulas.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/Formulas.java
index 357eb6a..86350f4 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/Formulas.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/Formulas.java
@@ -82,15 +82,6 @@
public static final double LONGITUDE_MAX = Numerics.MAX_INTEGER_CONVERTIBLE_TO_DOUBLE/2 * ANGULAR_TOLERANCE;
/**
- * The length of a <i>Julian year</i> in milliseconds.
- * From Wikipedia, <q>In astronomy, a Julian year (symbol: <b>a</b>) is a unit of measurement of time
- * defined as exactly 365.25 days of 86,400 SI seconds each.</q>.
- *
- * @see <a href="https://en.wikipedia.org/wiki/Julian_year_%28astronomy%29">Wikipedia: Julian year (astronomy)</a>
- */
- public static final long JULIAN_YEAR_LENGTH = 31557600000L;
-
- /**
* Maximum number of iterations for iterative computations. Defined in this {@code Formulas} class as a default value,
* but some classes may use a derived value (for example twice this amount). This constant is mostly useful for identifying
* places where iterations occur.
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/GeodeticObjectBuilder.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/GeodeticObjectBuilder.java
index 020b7df..42c5ae5 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/GeodeticObjectBuilder.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/GeodeticObjectBuilder.java
@@ -17,10 +17,10 @@
package org.apache.sis.referencing.privy;
import java.util.Map;
-import java.util.Date;
import java.util.Locale;
import java.util.Objects;
import java.util.function.BiConsumer;
+import java.time.temporal.Temporal;
import javax.measure.Unit;
import javax.measure.quantity.Time;
import javax.measure.quantity.Length;
@@ -61,6 +61,9 @@
import org.apache.sis.referencing.internal.Resources;
import org.apache.sis.parameter.Parameters;
+// Specific to the main branch:
+import org.apache.sis.util.privy.TemporalDate;
+
/**
* Helper methods for building Coordinate Reference Systems and related objects.
@@ -533,12 +536,12 @@
* Creates a temporal CRS from the given origin and temporal unit. For this method, the CRS name is optional:
* if no {@code addName(…)} method has been invoked, then a default name will be used.
*
- * @param origin the epoch in milliseconds since January 1st, 1970 at midnight UTC.
+ * @param origin the origin of the temporal datum.
* @param unit the unit of measurement.
* @return a temporal CRS using the given origin and units.
* @throws FactoryException if an error occurred while building the temporal CRS.
*/
- public TemporalCRS createTemporalCRS(final Date origin, final Unit<Time> unit) throws FactoryException {
+ public TemporalCRS createTemporalCRS(final Temporal origin, final Unit<Time> unit) throws FactoryException {
/*
* Try to use one of the predefined datum and coordinate system if possible.
* This not only saves a little bit of memory, but also provides better names.
@@ -582,7 +585,7 @@
if (datum == null) {
final Object remarks = properties.remove(TemporalCRS.REMARKS_KEY);
final Object identifier = properties.remove(TemporalCRS.IDENTIFIERS_KEY);
- datum = factories.getDatumFactory().createTemporalDatum(properties, origin);
+ datum = factories.getDatumFactory().createTemporalDatum(properties, TemporalDate.toDate(origin));
properties.put(TemporalCRS.IDENTIFIERS_KEY, identifier);
properties.put(TemporalCRS.REMARKS_KEY, remarks);
properties.put(TemporalCRS.NAME_KEY, datum.getName()); // Share the Identifier instance.
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/TemporalAccessor.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/TemporalAccessor.java
index 75bf192..02cd572 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/TemporalAccessor.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/TemporalAccessor.java
@@ -132,7 +132,7 @@
* @param target the target temporal extent.
*/
public void setTemporalExtent(final Envelope envelope, final DefaultTemporalExtent target) {
- target.setBounds(timeCRS.toDate(envelope.getMinimum(dimension)),
- timeCRS.toDate(envelope.getMaximum(dimension)));
+ target.setBounds(timeCRS.toInstant(envelope.getMinimum(dimension)),
+ timeCRS.toInstant(envelope.getMaximum(dimension)));
}
}
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/ElementTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/ElementTest.java
index 93c7d8a..409e88c 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/ElementTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/ElementTest.java
@@ -19,6 +19,7 @@
import java.util.Map;
import java.util.HashMap;
import java.util.Locale;
+import java.time.Instant;
import java.text.ParsePosition;
import java.text.ParseException;
import org.apache.sis.util.CharSequences;
@@ -26,7 +27,6 @@
// Test dependencies
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
-import org.apache.sis.test.TestUtilities;
import org.apache.sis.test.TestCase;
@@ -182,7 +182,7 @@
public void testPullDate() throws ParseException {
Element element = parse("TimeOrigin[1858-11-17T00:00:00.0Z]");
assertEquals("TimeOrigin", element.keyword);
- assertEquals(TestUtilities.date("1858-11-17 00:00:00"), element.pullDate("date"));
+ assertEquals(Instant.parse("1858-11-17T00:00:00Z"), element.pullDate("date"));
element.close(null);
}
@@ -222,7 +222,7 @@
assertEquals("Modified Julian", element.pullString("name"));
Element inner = element.pullElement(AbstractParser.MANDATORY, "TimeOrigin");
assertEquals("TimeOrigin", inner.keyword);
- assertEquals(TestUtilities.date("1858-11-17 00:00:00"), inner.pullDate("date"));
+ assertEquals(Instant.parse("1858-11-17T00:00:00Z"), inner.pullDate("date"));
inner.close(null);
element.close(null);
}
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
index a5d62e5..5d11c50 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
@@ -17,9 +17,9 @@
package org.apache.sis.io.wkt;
import java.util.Map;
-import java.util.Date;
import java.util.Iterator;
import java.util.Locale;
+import java.time.Instant;
import java.text.ParsePosition;
import java.text.ParseException;
import javax.measure.Unit;
@@ -43,7 +43,10 @@
import org.apache.sis.referencing.operation.transform.MathTransforms;
import org.apache.sis.referencing.operation.transform.LinearTransform;
import org.apache.sis.measure.Units;
-import static org.apache.sis.util.privy.StandardDateFormat.MILLISECONDS_PER_DAY;
+import static org.apache.sis.util.privy.Constants.SECONDS_PER_DAY;
+
+// Specific to the main and geoapi-3.1 branches:
+import org.apache.sis.util.privy.TemporalDate;
// Test dependencies
import org.junit.jupiter.api.Test;
@@ -1065,7 +1068,7 @@
final TemporalDatum timeDatum = timeCRS.getDatum();
assertNameAndIdentifierEqual("Time", 0, timeCRS);
assertNameAndIdentifierEqual("Modified Julian", 0, timeDatum);
- assertEquals(new Date(-40587L * MILLISECONDS_PER_DAY), timeDatum.getOrigin(), "epoch");
+ assertEquals(Instant.ofEpochSecond(-40587L * SECONDS_PER_DAY), TemporalDate.toTemporal(timeDatum.getOrigin()), "epoch");
// No more CRS.
assertFalse(components.hasNext());
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 14faed4..a4d9837 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
@@ -19,7 +19,10 @@
import java.util.Date;
import java.util.Map;
import java.util.HashMap;
+import java.util.Locale;
+import java.util.TimeZone;
import java.time.Instant;
+import java.text.SimpleDateFormat;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.IdentifiedObject;
@@ -46,9 +49,11 @@
import static org.apache.sis.test.Assertions.assertEqualsIgnoreMetadata;
import static org.apache.sis.test.Assertions.assertMessageContains;
import static org.apache.sis.test.TestUtilities.*;
+import static org.apache.sis.util.privy.Constants.UTC;
// Specific to the main branch:
import org.opengis.referencing.datum.VerticalDatumType;
+import org.apache.sis.util.privy.TemporalDate;
import static org.apache.sis.test.GeoapiAssert.assertAxisDirectionsEqual;
@@ -59,11 +64,6 @@
*/
public final class CommonCRSTest extends TestCase {
/**
- * Length of a day in milliseconds.
- */
- private static final double DAY_LENGTH = 24 * 60 * 60 * 1000;
-
- /**
* Creates a new test case.
*/
public CommonCRSTest() {
@@ -252,8 +252,20 @@
*/
@Test
public void testTemporal() {
- final double julianEpoch = CommonCRS.Temporal.JULIAN.datum().getOrigin().getTime() / DAY_LENGTH;
- assertTrue(julianEpoch < 0);
+ final var julianEpoch = TemporalDate.toInstant(CommonCRS.Temporal.JULIAN.datum().getOrigin());
+ final double SECONDS_PER_DAY = Constants.SECONDS_PER_DAY;
+ final double julianEpochSecond = julianEpoch.getEpochSecond() / SECONDS_PER_DAY;
+ assertTrue(julianEpochSecond < 0);
+ /*
+ * 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.
+ */
+ final var dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CANADA);
+ dateFormat.setTimeZone(TimeZone.getTimeZone(UTC));
+ dateFormat.setLenient(false);
+
for (final CommonCRS.Temporal e : CommonCRS.Temporal.values()) {
final String epoch;
final double days;
@@ -274,8 +286,8 @@
Validators.validate(crs);
assertSame(datum, e.datum(), name); // Datum before CRS creation.
assertSame(crs.getDatum(), e.datum(), name); // Datum after CRS creation.
- assertEquals(epoch, format(origin), name);
- assertEquals(days, origin.getTime() / DAY_LENGTH - julianEpoch, name);
+ assertEquals(epoch, dateFormat.format(origin), name);
+ assertEquals(days, origin.getTime() / (1000*SECONDS_PER_DAY) - julianEpochSecond, name);
switch (e) {
case JAVA: {
assertNameContains(datum, "Unix/POSIX");
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultTemporalCRSTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultTemporalCRSTest.java
index edfcb92..2ee0116 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultTemporalCRSTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/crs/DefaultTemporalCRSTest.java
@@ -22,8 +22,8 @@
import java.util.Map;
import org.apache.sis.referencing.datum.DefaultTemporalDatum;
import org.apache.sis.io.wkt.Convention;
-import static org.apache.sis.util.privy.StandardDateFormat.MILLISECONDS_PER_DAY;
-import static org.apache.sis.util.privy.StandardDateFormat.NANOS_PER_MILLISECOND;
+import static org.apache.sis.util.privy.Constants.MILLISECONDS_PER_DAY;
+import static org.apache.sis.util.privy.Constants.NANOS_PER_MILLISECOND;
// Test dependencies
import org.junit.jupiter.api.Test;
@@ -109,10 +109,10 @@
*/
@Test
public void testDateConversionWithNanos() {
- final DefaultTemporalDatum datum = new DefaultTemporalDatum(
+ final var datum = new DefaultTemporalDatum(
Map.of(DefaultTemporalDatum.NAME_KEY, "For test"),
- new Date(10000L * MILLISECONDS_PER_DAY + 12345)); // 1997-05-19T00:00:12.345Z
- final DefaultTemporalCRS crs = new DefaultTemporalCRS(
+ Instant.ofEpochMilli(10000L * MILLISECONDS_PER_DAY + 12345)); // 1997-05-19T00:00:12.345Z
+ final var crs = new DefaultTemporalCRS(
Map.of(DefaultTemporalCRS.NAME_KEY, datum.getName()),
datum, HardCodedCS.DAYS);
/*
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/BursaWolfParametersTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/BursaWolfParametersTest.java
index 9c85951..a97e6cd 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/BursaWolfParametersTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/BursaWolfParametersTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.sis.referencing.datum;
-import java.util.Date;
import org.opengis.referencing.operation.Matrix;
import org.apache.sis.metadata.iso.extent.Extents;
import org.apache.sis.metadata.iso.extent.DefaultExtent;
@@ -105,7 +104,7 @@
}
/**
- * Invokes {@link BursaWolfParameters#getPositionVectorTransformation(Date)}
+ * Invokes {@link BursaWolfParameters#getPositionVectorTransformation(Temporal)}
* and compares with our own matrix calculated using double arithmetic.
*/
private static MatrixSIS getPositionVectorTransformation(final BursaWolfParameters p) {
@@ -150,7 +149,7 @@
}
/**
- * Tests {@link BursaWolfParameters#getPositionVectorTransformation(Date)}.
+ * Tests {@link BursaWolfParameters#getPositionVectorTransformation(Temporal)}.
* This test transform a point from WGS72 to WGS84, and conversely,
* as documented in the example section of EPSG operation method 9606.
*
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java
index fbf6fee..0adab08 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java
@@ -16,13 +16,13 @@
*/
package org.apache.sis.referencing.datum;
-import java.util.Date;
import java.util.HashMap;
+import java.time.ZoneOffset;
+import java.time.OffsetDateTime;
import java.io.InputStream;
import jakarta.xml.bind.JAXBException;
import org.apache.sis.io.wkt.Convention;
import org.apache.sis.referencing.ImmutableIdentifier;
-import static org.apache.sis.util.privy.StandardDateFormat.MILLISECONDS_PER_DAY;
// Test dependencies
import org.junit.jupiter.api.Test;
@@ -38,6 +38,9 @@
import static org.opengis.referencing.ReferenceSystem.*;
import static org.apache.sis.test.GeoapiAssert.assertIdentifierEquals;
+// Specific to the main and geoapi-3.1 branches:
+import org.apache.sis.util.privy.TemporalDate;
+
/**
* Tests the {@link DefaultTemporalDatum} class.
@@ -62,14 +65,16 @@
}
/**
- * November 17, 1858 at 00:00 UTC as a Java timestamp.
+ * November 17, 1858 at 00:00 UTC.
*/
- private static final long ORIGIN = -40587L * MILLISECONDS_PER_DAY;
+ private static final OffsetDateTime ORIGIN = OffsetDateTime.of(1858, 11, 17, 0, 0, 0, 0, ZoneOffset.UTC);
/**
* Creates the temporal datum to use for testing purpose.
+ *
+ * @param local whether the datum origin should be a local date.
*/
- private static DefaultTemporalDatum create() {
+ private static DefaultTemporalDatum create(final boolean local) {
final var properties = new HashMap<String,Object>(4);
assertNull(properties.put(IDENTIFIERS_KEY,
new ImmutableIdentifier(HardCodedCitations.SIS, "SIS", "MJ")));
@@ -77,7 +82,7 @@
assertNull(properties.put(SCOPE_KEY, "History."));
assertNull(properties.put(REMARKS_KEY,
"Time measured as days since November 17, 1858 at 00:00 UTC."));
- return new DefaultTemporalDatum(properties, new Date(ORIGIN));
+ return new DefaultTemporalDatum(properties, local ? ORIGIN.toLocalDate() : ORIGIN);
}
/**
@@ -85,7 +90,7 @@
*/
@Test
public void testConsistency() {
- assertEquals(HardCodedDatum.MODIFIED_JULIAN.getOrigin(), new Date(ORIGIN));
+ assertEquals(TemporalDate.toTemporal(HardCodedDatum.MODIFIED_JULIAN.getOrigin()), ORIGIN.toInstant());
}
/**
@@ -98,7 +103,7 @@
*/
@Test
public void testToWKT() {
- final DefaultTemporalDatum datum = create();
+ final DefaultTemporalDatum datum = create(true);
assertWktEquals(Convention.WKT1, "TDATUM[“Modified Julian”, TIMEORIGIN[1858-11-17], AUTHORITY[“SIS”, “MJ”]]", datum);
assertWktEquals(Convention.WKT2, "TDATUM[“Modified Julian”, TIMEORIGIN[1858-11-17], ID[“SIS”, “MJ”]]", datum);
assertWktEquals(Convention.WKT2_SIMPLIFIED, "TimeDatum[“Modified Julian”, TimeOrigin[1858-11-17], Id[“SIS”, “MJ”]]", datum);
@@ -111,7 +116,7 @@
*/
@Test
public void testMarshalling() throws JAXBException {
- final DefaultTemporalDatum datum = create();
+ final DefaultTemporalDatum datum = create(false);
assertMarshalEqualsFile(openTestFile(), datum, "xmlns:*", "xsi:schemaLocation");
}
@@ -128,6 +133,6 @@
assertEquals("Modified Julian", datum.getName().getCode());
assertRemarksEquals("Time measured as days since November 17, 1858 at 00:00 UTC.", datum, null);
assertEquals("History.", getScope(datum));
- assertEquals(new Date(ORIGIN), datum.getOrigin());
+ assertEquals(ORIGIN, TemporalDate.toTemporal(datum.getOrigin()));
}
}
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/HardCodedDatum.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/HardCodedDatum.java
index 43903a2..e79d091 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/HardCodedDatum.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/HardCodedDatum.java
@@ -16,14 +16,14 @@
*/
package org.apache.sis.referencing.datum;
-import java.util.Date;
import java.util.Map;
import java.util.HashMap;
+import java.time.Instant;
import org.opengis.referencing.datum.PixelInCell;
import org.apache.sis.referencing.NamedIdentifier;
import org.apache.sis.referencing.internal.VerticalDatumTypes;
import org.apache.sis.measure.Units;
-import static org.apache.sis.util.privy.StandardDateFormat.MILLISECONDS_PER_DAY;
+import static org.apache.sis.util.privy.Constants.SECONDS_PER_DAY;
// Test dependencies
import org.apache.sis.metadata.iso.citation.HardCodedCitations;
@@ -134,14 +134,14 @@
*/
public static final DefaultTemporalDatum UNIX = new DefaultTemporalDatum(
properties("UNIX", null, null),
- new Date(0));
+ Instant.EPOCH);
/**
* Default datum for time measured since November 17, 1858 at 00:00 UTC.
*/
public static final DefaultTemporalDatum MODIFIED_JULIAN = new DefaultTemporalDatum(
properties("Modified Julian", null, null),
- new Date(-40587L * MILLISECONDS_PER_DAY));
+ Instant.ofEpochSecond(-40587L * SECONDS_PER_DAY));
/**
* A parametric datum for day of year, without any particular year.
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/TimeDependentBWPTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/TimeDependentBWPTest.java
index 471c5fb..9aca865 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/TimeDependentBWPTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/TimeDependentBWPTest.java
@@ -16,18 +16,19 @@
*/
package org.apache.sis.referencing.datum;
-import java.util.Date;
+import java.time.Instant;
+import java.time.temporal.Temporal;
+import java.time.temporal.ChronoField;
import org.opengis.referencing.operation.Matrix;
import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
import org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException;
-import static org.apache.sis.referencing.privy.Formulas.JULIAN_YEAR_LENGTH;
+import static org.apache.sis.util.privy.Constants.MILLIS_PER_TROPICAL_YEAR;
// 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;
// Specific to the main branch:
import static org.apache.sis.test.GeoapiAssert.assertMatrixEquals;
@@ -51,7 +52,7 @@
* For the purpose of this test, the target datum does not matter anyway.
*/
private static TimeDependentBWP create() {
- final TimeDependentBWP p = new TimeDependentBWP(GeodeticDatumMock.WGS84, null, date("1994-01-01 00:00:00"));
+ final var p = new TimeDependentBWP(GeodeticDatumMock.WGS84, null, Instant.parse("1994-01-01T00:00:00Z"));
p.tX = -0.08468; p.dtX = +1.42;
p.tY = -0.01942; p.dtY = +1.34;
p.tZ = +0.03201; p.dtZ = +0.90;
@@ -101,9 +102,11 @@
* geocentric coordinates on ITRF2008 at epoch 2013.9.
*/
final TimeDependentBWP p = create();
- final Date time = p.getTimeReference();
- time.setTime(time.getTime() + StrictMath.round((2013.9 - 1994) * JULIAN_YEAR_LENGTH));
- assertEquals(date("2013-11-25 11:24:00"), time);
+ Temporal time = p.getTimeReference();
+ long t = time.getLong(ChronoField.INSTANT_SECONDS);
+ t += StrictMath.round((2013.9 - 1994) * (MILLIS_PER_TROPICAL_YEAR / 1000.0));
+ time = Instant.ofEpochSecond(t);
+ assertEquals(Instant.parse("2013-11-25T07:40:16Z"), time);
/*
* Transform the point given in the EPSG example and compare with the coordinate
* that we obtain if we do the calculation ourself using the intermediate values
@@ -124,7 +127,7 @@
}
/**
- * Compares the coordinates calculated with the {@link TimeDependentBWP#getPositionVectorTransformation(Date)}
+ * Compares the coordinates calculated with the {@link TimeDependentBWP#getPositionVectorTransformation(Temporal)}
* matrix with the coordinates calculated ourselves from the numbers given in the EPSG examples. Note that the
* EPSG documentation truncates the numerical values given in their example, so it is normal that we have a
* slight difference.
@@ -182,7 +185,7 @@
* We find a difference of 13, 9 and 3 millimetres along the X, Y and Z axis respectively.
*
* <p>The purpose of this test is to ensure that we get the same errors when calculating from the corrected values
- * provided by EPSG, rather than as an error in {@link TimeDependentBWP#getPositionVectorTransformation(Date)}</p>
+ * provided by EPSG, rather than as an error in {@link TimeDependentBWP#getPositionVectorTransformation(Temporal)}</p>
*/
@Test
public void testEpsgCalculation() {
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/ConcurrentAuthorityFactoryTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/ConcurrentAuthorityFactoryTest.java
index ffc67ff..e9bf014 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/ConcurrentAuthorityFactoryTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/ConcurrentAuthorityFactoryTest.java
@@ -24,7 +24,7 @@
import java.util.function.Supplier;
import java.lang.reflect.Field;
import org.opengis.util.FactoryException;
-import static org.apache.sis.util.privy.StandardDateFormat.NANOS_PER_MILLISECOND;
+import static org.apache.sis.util.privy.Constants.NANOS_PER_MILLISECOND;
// Test dependencies
import org.junit.jupiter.api.Test;
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/ServicesForMetadataTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/ServicesForMetadataTest.java
index c64bf5b..d0c73dd 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/ServicesForMetadataTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/ServicesForMetadataTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.sis.referencing.internal;
-import java.util.Date;
import org.opengis.geometry.Envelope;
import org.opengis.metadata.extent.GeographicBoundingBox;
import org.opengis.metadata.extent.VerticalExtent;
@@ -24,7 +23,6 @@
import org.opengis.referencing.operation.TransformException;
import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
import org.apache.sis.metadata.iso.extent.DefaultVerticalExtent;
-import org.apache.sis.metadata.iso.extent.DefaultTemporalExtent;
import org.apache.sis.metadata.iso.extent.DefaultSpatialTemporalExtent;
import org.apache.sis.geometry.GeneralEnvelope;
import org.apache.sis.referencing.CommonCRS;
@@ -33,7 +31,6 @@
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 org.apache.sis.referencing.crs.HardCodedCRS;
import static org.apache.sis.test.Assertions.assertEqualsIgnoreMetadata;
import static org.apache.sis.test.TestUtilities.getSingleton;
@@ -66,7 +63,7 @@
*/
@SuppressWarnings("fallthrough")
private static GeneralEnvelope createEnvelope(final CoordinateReferenceSystem crs) {
- final GeneralEnvelope envelope = new GeneralEnvelope(crs);
+ final var envelope = new GeneralEnvelope(crs);
switch (crs.getCoordinateSystem().getDimension()) {
default: throw new AssertionError();
case 4: envelope.setRange(3, 51000, 52000); // Fall through
@@ -106,7 +103,7 @@
*/
@Test
public void testSetGeographicBoundsFrom3D() throws TransformException {
- final DefaultGeographicBoundingBox box = new DefaultGeographicBoundingBox();
+ final var box = new DefaultGeographicBoundingBox();
box.setBounds(createEnvelope(HardCodedCRS.WGS84_3D));
verifySpatialExtent(box);
}
@@ -119,7 +116,7 @@
*/
@Test
public void testSetGeographicBoundsFrom4D() throws TransformException {
- final DefaultGeographicBoundingBox box = new DefaultGeographicBoundingBox();
+ final var box = new DefaultGeographicBoundingBox();
box.setBounds(createEnvelope(HardCodedCRS.GEOID_4D));
verifySpatialExtent(box);
}
@@ -132,7 +129,7 @@
*/
@Test
public void testSetVerticalBoundsFromEllipsoid() throws TransformException {
- final DefaultVerticalExtent extent = new DefaultVerticalExtent();
+ final var extent = new DefaultVerticalExtent();
extent.setBounds(createEnvelope(HardCodedCRS.WGS84_3D));
verifyVerticalExtent(CommonCRS.Vertical.ELLIPSOIDAL, extent);
}
@@ -145,7 +142,7 @@
*/
@Test
public void testSetVerticalBoundsFromGeoid() throws TransformException {
- final DefaultVerticalExtent extent = new DefaultVerticalExtent();
+ final var extent = new DefaultVerticalExtent();
extent.setBounds(createEnvelope(HardCodedCRS.GEOID_4D));
verifyVerticalExtent(CommonCRS.Vertical.MEAN_SEA_LEVEL, extent);
}
@@ -157,7 +154,7 @@
*/
@Test
public void testSetSpatialTemporalBounds() throws TransformException {
- final DefaultSpatialTemporalExtent extent = new DefaultSpatialTemporalExtent();
+ final var extent = new DefaultSpatialTemporalExtent();
extent.setBounds(createEnvelope(HardCodedCRS.GEOID_3D));
verifySpatialExtent((GeographicBoundingBox) getSingleton(extent.getSpatialExtent()));
verifyVerticalExtent(CommonCRS.Vertical.MEAN_SEA_LEVEL, extent.getVerticalExtent());
@@ -171,7 +168,7 @@
*/
@Test
public void testSetGeographicBoundsCrossingAntimeridian() throws TransformException {
- final DefaultGeographicBoundingBox box = new DefaultGeographicBoundingBox();
+ final var box = new DefaultGeographicBoundingBox();
final GeneralEnvelope envelope = createEnvelope(HardCodedCRS.WGS84);
envelope.setRange(0, 170, 195);
box.setBounds(envelope);
@@ -193,29 +190,9 @@
*/
@Test
public void testVerticalIntersection() throws TransformException {
- final DefaultVerticalExtent e1 = new DefaultVerticalExtent(1000, 2000, HardCodedCRS.ELLIPSOIDAL_HEIGHT_cm);
- final DefaultVerticalExtent e2 = new DefaultVerticalExtent(15, 25, HardCodedCRS.ELLIPSOIDAL_HEIGHT);
+ final var e1 = new DefaultVerticalExtent(1000, 2000, HardCodedCRS.ELLIPSOIDAL_HEIGHT_cm);
+ final var e2 = new DefaultVerticalExtent(15, 25, HardCodedCRS.ELLIPSOIDAL_HEIGHT);
e1.intersect(e2);
assertEquals(new DefaultVerticalExtent(1500, 2000, HardCodedCRS.ELLIPSOIDAL_HEIGHT_cm), e1);
}
-
- /**
- * Tests {@link DefaultTemporalExtent#intersect(TemporalExtent)}.
- *
- * @throws TransformException if the transformation failed.
- */
- @Test
- public void testTemporalIntersection() throws TransformException {
- final DefaultTemporalExtent e1 = new DefaultTemporalExtent();
- final DefaultTemporalExtent e2 = new DefaultTemporalExtent();
- final Date t1 = TestUtilities.date("2016-12-05 19:45:20");
- final Date t2 = TestUtilities.date("2017-02-18 02:12:50");
- final Date t3 = TestUtilities.date("2017-11-30 23:50:00");
- final Date t4 = TestUtilities.date("2018-05-20 12:30:45");
- e1.setBounds(t1, t3);
- e2.setBounds(t2, t4);
- e1.intersect(e2);
- assertEquals(t2, e1.getStartTime(), "startTime");
- assertEquals(t3, e1.getEndTime(), "endTime");
- }
}
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
index fa221a1..d1c91e7 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
@@ -52,6 +52,7 @@
import org.apache.sis.referencing.crs.DefaultDerivedCRS;
import org.apache.sis.io.wkt.WKTFormat;
import org.apache.sis.measure.Units;
+import static org.apache.sis.util.privy.Constants.SECONDS_PER_DAY;
import static org.apache.sis.referencing.privy.Formulas.LINEAR_TOLERANCE;
import static org.apache.sis.referencing.privy.Formulas.ANGULAR_TOLERANCE;
import static org.apache.sis.referencing.privy.PositionalAccuracyConstant.DATUM_SHIFT_APPLIED;
@@ -951,7 +952,7 @@
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 0, 0,
- 0, 0, 1./(24*60*60), 40587,
+ 0, 0, 1./SECONDS_PER_DAY, 40587,
0, 0, 0, 1
}), linear.getMatrix(), 1E-12, "transform.matrix");
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/projection/MercatorMethodComparison.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/projection/MercatorMethodComparison.java
index 30f40d4..d83bdc2 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/projection/MercatorMethodComparison.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/projection/MercatorMethodComparison.java
@@ -26,7 +26,7 @@
import org.apache.sis.math.StatisticsFormat;
import org.apache.sis.referencing.internal.Resources;
import org.apache.sis.metadata.privy.ReferencingServices;
-import static org.apache.sis.util.privy.StandardDateFormat.NANOS_PER_SECOND;
+import static org.apache.sis.util.privy.Constants.NANOS_PER_SECOND;
// Test dependencies
import org.apache.sis.test.Benchmark;
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/projection/ProjectionBenchmark.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/projection/ProjectionBenchmark.java
index cd093e9..673af07 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/projection/ProjectionBenchmark.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/projection/ProjectionBenchmark.java
@@ -28,7 +28,6 @@
import org.apache.sis.measure.Latitude;
import org.apache.sis.parameter.Parameters;
import org.apache.sis.util.privy.Constants;
-import org.apache.sis.util.privy.StandardDateFormat;
import org.apache.sis.referencing.operation.provider.AbstractProvider;
import org.apache.sis.referencing.operation.transform.LinearTransform;
import org.apache.sis.referencing.operation.transform.MathTransforms;
@@ -219,7 +218,7 @@
long time = System.nanoTime();
projection.transform(sources, 0, targets, 0, NUM_POINTS);
time = System.nanoTime() - time;
- final double seconds = time / (double) StandardDateFormat.NANOS_PER_SECOND;
+ final double seconds = time / (double) Constants.NANOS_PER_SECOND;
System.out.printf("%s time: %1.4f%n", performance.name(), seconds);
performance.accept(seconds);
}
@@ -235,7 +234,7 @@
kernel.transform(targets, 0, targets, 0, NUM_POINTS);
time = System.nanoTime() - time;
denormalize.transform(targets, 0, targets, 0, NUM_POINTS);
- final double seconds = time / (double) StandardDateFormat.NANOS_PER_SECOND;
+ final double seconds = time / (double) Constants.NANOS_PER_SECOND;
System.out.printf("%s time: %1.4f%n", performance.name(), seconds);
performance.accept(seconds);
}
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/privy/ExtentSelectorTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/privy/ExtentSelectorTest.java
index d8a05fa..41758cb 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/privy/ExtentSelectorTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/privy/ExtentSelectorTest.java
@@ -16,7 +16,7 @@
*/
package org.apache.sis.referencing.privy;
-import java.util.Date;
+import java.time.Instant;
import java.time.Duration;
import org.opengis.metadata.extent.Extent;
import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
@@ -150,11 +150,11 @@
* {@code true} for associating a larger geographic area.
*/
private static Extent time(final long startTime, final long endTime, final boolean largeArea) {
- final DefaultGeographicBoundingBox bbox = new DefaultGeographicBoundingBox(
+ final var bbox = new DefaultGeographicBoundingBox(
largeArea ? -20 : -10, 10,
largeArea ? 10 : 20, 30);
- final DefaultTemporalExtent range = new DefaultTemporalExtent();
- range.setBounds(new Date(startTime), new Date(endTime));
+ final var range = new DefaultTemporalExtent();
+ range.setBounds(Instant.ofEpochMilli(startTime), Instant.ofEpochMilli(endTime));
return new DefaultExtent(null, bbox, null, range);
}
@@ -162,7 +162,7 @@
* Creates the selector to use for testing purpose.
*/
private ExtentSelector<Integer> create(final Extent aoi) {
- ExtentSelector<Integer> selector = new ExtentSelector<>(aoi);
+ final var selector = new ExtentSelector<Integer>(aoi);
selector.alternateOrdering = alternateOrdering;
selector.setTimeGranularity(granularity);
return selector;
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/privy/FormulasTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/privy/FormulasTest.java
index 55ed090..6bb6d68 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/privy/FormulasTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/privy/FormulasTest.java
@@ -52,14 +52,6 @@
}
/**
- * Verifies the {@link Formulas#JULIAN_YEAR_LENGTH} constant.
- */
- @Test
- public void verifyJulianYearLength() {
- assertEquals(StrictMath.round(365.25 * 24 * 60 * 60 * 1000), Formulas.JULIAN_YEAR_LENGTH);
- }
-
- /**
* Tests {@link Formulas#isPoleToPole(double, double)}.
*/
@Test
diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/MetadataTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/MetadataTest.java
index b66a6e2..06fcd20 100644
--- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/MetadataTest.java
+++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/MetadataTest.java
@@ -23,6 +23,7 @@
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
+import java.time.Instant;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import jakarta.xml.bind.Marshaller;
@@ -244,7 +245,8 @@
nameAndIdentifier("D28", "Depth below D28", "CRS for testing purpose"), datum, cs);
final var temporal = new DefaultTemporalExtent();
- temporal.setBounds(TestUtilities.date("1990-06-05 00:00:00"), TestUtilities.date("1990-07-02 00:00:00"));
+ temporal.setBounds(Instant.parse("1990-06-05T00:00:00Z"),
+ Instant.parse("1990-07-02T00:00:00Z"));
identification.setExtents(Set.of(new DefaultExtent(
null,
new DefaultGeographicBoundingBox(1.1666, 1.1667, 36.4, 36.6),
diff --git a/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/MetadataReader.java b/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/MetadataReader.java
index c5a5199..81d0d7f 100644
--- a/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/MetadataReader.java
+++ b/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/MetadataReader.java
@@ -23,7 +23,6 @@
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.Arrays;
-import java.util.Date;
import java.util.Locale;
import java.util.EnumMap;
import java.util.regex.Matcher;
@@ -64,7 +63,6 @@
import org.apache.sis.referencing.operation.provider.PolarStereographicB;
import org.apache.sis.referencing.operation.provider.TransverseMercator;
import org.apache.sis.storage.base.MetadataBuilder;
-import org.apache.sis.util.privy.StandardDateFormat;
import org.apache.sis.util.privy.Constants;
import org.apache.sis.util.privy.Strings;
import static org.apache.sis.util.privy.CollectionsExt.singletonOrNull;
@@ -429,8 +427,7 @@
* Example: "2014-03-12T06:06:35Z".
*/
case "FILE_DATE": {
- addCitationDate(StandardDateFormat.toDate(OffsetDateTime.parse(value)),
- DateType.CREATION, MetadataBuilder.Scope.ALL);
+ addCitationDate(OffsetDateTime.parse(value), DateType.CREATION, MetadataBuilder.Scope.ALL);
break;
}
/*
@@ -809,9 +806,8 @@
final Temporal st = sceneTime;
if (st != null) {
sceneTime = null; // Clear now in case an exception it thrown below.
- final Date t = StandardDateFormat.toDate(st);
- addAcquisitionTime(t);
- addTemporalExtent(t, t);
+ addAcquisitionTime(st);
+ addTemporalExtent(st, st);
}
}
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
index 960d1b7..723f165 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
@@ -1011,7 +1011,7 @@
*/
case TAG_DATE_TIME: {
for (final String value : type.readAsStrings(input(), count, encoding())) {
- metadata.addCitationDate(reader.store.getDateFormat().parse(value),
+ metadata.addCitationDate(reader.store.getDateFormat().parse(value).toInstant(),
DateType.CREATION, ImageMetadataBuilder.Scope.RESOURCE);
}
break;
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java
index 24a489a..2f2a65f 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/CRSBuilder.java
@@ -1141,6 +1141,7 @@
if (!Units.METRE.equals(linearUnit)) {
cs = replaceLinearUnit(cs, linearUnit);
}
+ // TODO: datum should be DatumEnsemble for some case such as EPSG:4326.
final GeodeticCRS crs = getCRSFactory().createGeocentricCRS(properties(getOrDefault(names, GCRS)), datum, cs);
lastName = crs.getName();
return crs;
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java
index 73ac736..868fff0 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java
@@ -18,7 +18,6 @@
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.Map;
@@ -28,6 +27,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.io.IOException;
+import java.time.temporal.Temporal;
import ucar.nc2.constants.CF; // String constants are copied by the compiler with no UCAR reference left.
import ucar.nc2.constants.CDM; // idem
import ucar.nc2.constants.ACDD; // idem
@@ -757,18 +757,18 @@
hasExtent = true;
}
/*
- * Get the start and end times as Date objects if available, or as numeric values otherwise.
- * In the latter case, the unit symbol tells how to convert to Date objects.
+ * Get the start and end times as temporal objects if available, or as numeric values otherwise.
+ * In the latter case, the unit symbol tells how to convert to temporal objects.
*/
- Date startTime = decoder.dateValue(TIME.MINIMUM);
- Date endTime = decoder.dateValue(TIME.MAXIMUM);
+ Temporal startTime = decoder.dateValue(TIME.MINIMUM);
+ Temporal endTime = decoder.dateValue(TIME.MAXIMUM);
if (startTime == null && endTime == null) {
final Number tmin = decoder.numericValue(TIME.MINIMUM);
final Number tmax = decoder.numericValue(TIME.MAXIMUM);
if (tmin != null || tmax != null) {
final String symbol = stringValue(TIME.UNITS);
if (symbol != null) {
- final Date[] dates = decoder.numberToDate(symbol, tmin, tmax);
+ final Temporal[] dates = decoder.numberToDate(symbol, tmin, tmax);
startTime = dates[0];
endTime = dates[1];
}
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/AxisType.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/AxisType.java
index 604b907..a66b1c9 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/AxisType.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/AxisType.java
@@ -18,7 +18,6 @@
import java.util.Map;
import java.util.HashMap;
-import java.util.Locale;
import ucar.nc2.constants.CF; // String constants are copied by the compiler with no UCAR reference left.
import javax.measure.Unit;
import org.opengis.referencing.cs.AxisDirection;
@@ -100,7 +99,7 @@
* @return axis abbreviation for the given type or name, or {@code null} if none.
*/
private static Character abbreviation(final String type) {
- return (type != null) ? TYPES.get(type.toLowerCase(Locale.US)) : null;
+ return (type != null) ? TYPES.get(type.toLowerCase(Decoder.DATA_LOCALE)) : null;
}
/**
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/CRSBuilder.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/CRSBuilder.java
index 843266b..1e280ae 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/CRSBuilder.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/CRSBuilder.java
@@ -18,7 +18,6 @@
import java.util.Map;
import java.util.List;
-import java.util.Date;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.StringJoiner;
@@ -61,6 +60,7 @@
import org.apache.sis.measure.Units;
// Specific to the main branch:
+import org.apache.sis.util.privy.TemporalDate;
import org.apache.sis.referencing.factory.GeodeticObjectFactory;
@@ -136,6 +136,7 @@
/**
* The datum created by {@link #createDatum(DatumFactory, Map)}.
+ * At least one of {@code datum} and {@link #datumEnsemble} shall be initialized.
*/
protected D datum;
@@ -968,7 +969,7 @@
datum = c.datum();
} else {
properties = properties("Time since " + epoch);
- datum = factory.createTemporalDatum(properties, Date.from(epoch));
+ datum = factory.createTemporalDatum(properties, TemporalDate.toDate(epoch));
}
}
}
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Convention.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Convention.java
index 1a25de6..0791290 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Convention.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Convention.java
@@ -21,7 +21,6 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
-import java.util.Locale;
import java.util.ServiceLoader;
import java.util.function.Function;
import java.awt.Color;
@@ -482,7 +481,7 @@
final Map<String,Object> definition = new HashMap<>();
definition.put(CF.GRID_MAPPING_NAME, method);
for (final String name : node.getAttributeNames()) try {
- final String ln = name.toLowerCase(Locale.US);
+ final String ln = name.toLowerCase(Decoder.DATA_LOCALE);
Object value;
switch (ln) {
case CF.GRID_MAPPING_NAME: continue; // Already stored.
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Decoder.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Decoder.java
index abee3b6..a5cfe8b 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Decoder.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Decoder.java
@@ -22,12 +22,14 @@
import java.util.HashMap;
import java.util.Collection;
import java.util.Objects;
-import java.util.Date;
-import java.util.TimeZone;
+import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.Level;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.temporal.Temporal;
import java.io.IOException;
import java.nio.file.Path;
import ucar.nc2.constants.CF; // String constants are copied by the compiler with no UCAR reference left.
@@ -45,7 +47,7 @@
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.logging.PerformanceLevel;
import org.apache.sis.util.collection.TreeTable;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
import org.apache.sis.util.iso.DefaultNameFactory;
import org.apache.sis.referencing.privy.ReferencingFactoryContainer;
@@ -74,6 +76,13 @@
public static final String FORMAT_NAME = "netCDF";
/**
+ * The locale of data such as number formats, dates and names.
+ * This is used, for example, for the conversion to lower-cases before case-insensitive searches.
+ * This is not the locale for error messages or warnings reported to the user.
+ */
+ public static final Locale DATA_LOCALE = Locale.US;
+
+ /**
* The path to the netCDF file, or {@code null} if unknown.
* This is set by netCDF store constructor and shall not be modified afterward.
* This is used for information purpose only, not for actual reading operation.
@@ -326,7 +335,7 @@
* @param name the name of the attribute to search, or {@code null}.
* @return the attribute value, or {@code null} if none or unparsable or if the given name was null.
*/
- public abstract Date dateValue(String name);
+ public abstract Temporal dateValue(String name);
/**
* Converts the given numerical values to date, using the information provided in the given unit symbol.
@@ -336,15 +345,15 @@
* @param values the values to convert. May contains {@code null} elements.
* @return the converted values. May contains {@code null} elements.
*/
- public abstract Date[] numberToDate(String symbol, Number... values);
+ public abstract Temporal[] numberToDate(String symbol, Number... values);
/**
* Returns the timezone for decoding dates. Currently fixed to UTC.
*
* @return the timezone for dates.
*/
- public TimeZone getTimeZone() {
- return TimeZone.getTimeZone(StandardDateFormat.UTC);
+ public ZoneId getTimeZone() {
+ return ZoneOffset.UTC;
}
/**
@@ -508,7 +517,7 @@
final Logger logger = listeners.getLogger();
if (logger.isLoggable(level)) {
final LogRecord record = resources().getLogRecord(level, resourceKey,
- getFilename(), time / (double) StandardDateFormat.NANOS_PER_SECOND);
+ getFilename(), time / (double) Constants.NANOS_PER_SECOND);
Logging.completeAndLog(logger, caller, method, record);
}
}
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/GridMapping.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/GridMapping.java
index 95d93cf..6e99cec 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/GridMapping.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/GridMapping.java
@@ -21,6 +21,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
+import java.util.TimeZone;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.function.Supplier;
@@ -508,11 +509,11 @@
}
/**
- * Creates a coordinate reference system by parsing a Well Known Text (WKT) string. The WKT is presumed
- * to use the GDAL flavor of WKT 1, and warnings are redirected to decoder listeners.
+ * Creates a coordinate reference system by parsing a Well Known Text (WKT) string.
+ * The WKT is presumed to use the GDAL flavor of WKT 1, and warnings are redirected to decoder listeners.
*/
private static CoordinateReferenceSystem createFromWKT(final Node node, final String wkt) throws ParseException {
- final WKTFormat f = new WKTFormat(node.getLocale(), node.decoder.getTimeZone());
+ final WKTFormat f = new WKTFormat(Decoder.DATA_LOCALE, TimeZone.getTimeZone(node.decoder.getTimeZone()));
f.setConvention(org.apache.sis.io.wkt.Convention.WKT1_COMMON_UNITS);
final CoordinateReferenceSystem crs = (CoordinateReferenceSystem) f.parseObject(wkt);
final Warnings warnings = f.getWarnings();
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/HYCOM.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/HYCOM.java
index c583ce9..543f9f1 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/HYCOM.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/HYCOM.java
@@ -18,14 +18,14 @@
import java.io.IOException;
import java.time.Instant;
-import java.util.Locale;
+import java.util.TimeZone;
import java.util.GregorianCalendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.sis.math.Vector;
import org.apache.sis.measure.Units;
import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
/**
@@ -102,7 +102,7 @@
*/
Vector values = variable.read();
final double[] times = new double[values.size()];
- final GregorianCalendar calendar = new GregorianCalendar(decoder.getTimeZone(), Locale.US);
+ final GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone(decoder.getTimeZone()), Decoder.DATA_LOCALE);
calendar.clear();
for (int i=0; i<times.length; i++) {
double time = values.doubleValue(i); // Date encoded as a double (e.g. 20181017)
@@ -112,7 +112,7 @@
int month = (int) (date % 100); date /= 100;
calendar.set(Math.toIntExact(date), month - 1, day, 0, 0, 0);
date = calendar.getTimeInMillis() - origin; // Milliseconds since epoch.
- time += date / (double) StandardDateFormat.MILLISECONDS_PER_DAY;
+ time += date / (double) Constants.MILLISECONDS_PER_DAY;
times[i] = time;
}
variable.setValues(times);
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Variable.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Variable.java
index 58d8b72..06739b6 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Variable.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Variable.java
@@ -20,7 +20,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
-import java.util.Locale;
import java.util.regex.Pattern;
import java.io.IOException;
import java.time.Instant;
@@ -1286,7 +1285,7 @@
* @param buffer the buffer when to append the name of the variable data type.
*/
public final void writeDataTypeName(final StringBuilder buffer) {
- buffer.append(getDataType().name().toLowerCase(Locale.US));
+ buffer.append(getDataType().name().toLowerCase(Decoder.DATA_LOCALE));
final List<Dimension> dimensions = getGridDimensions();
for (int i=dimensions.size(); --i>=0;) {
dimensions.get(i).writeLength(buffer);
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/ChannelDecoder.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/ChannelDecoder.java
index 9e1b23e..a91de60 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/ChannelDecoder.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/ChannelDecoder.java
@@ -28,7 +28,6 @@
import java.util.IdentityHashMap;
import java.util.List;
import java.util.ArrayList;
-import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.time.DateTimeException;
@@ -37,6 +36,8 @@
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.channels.ReadableByteChannel;
+import java.time.Instant;
+import java.time.temporal.Temporal;
import javax.measure.UnitConverter;
import javax.measure.IncommensurableException;
import javax.measure.format.MeasurementParseException;
@@ -58,6 +59,7 @@
import org.apache.sis.util.privy.Constants;
import org.apache.sis.util.privy.CollectionsExt;
import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.TemporalDate;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.collection.TreeTable;
@@ -104,14 +106,6 @@
*/
private static final Charset NAME_ENCODING = StandardCharsets.UTF_8;
- /**
- * The locale of dimension, variable and attribute names. This is used for the conversion to
- * lower-cases before case-insensitive searches.
- *
- * @see #findAttribute(String)
- */
- static final Locale NAME_LOCALE = Locale.US;
-
/*
* NOTE: the names of the static constants below this point match the names used in the Backus-Naur Form (BNF)
* definitions in the netCDF Classic and 64-bit Offset Format (1.0) specification (link in class javdoc),
@@ -289,7 +283,7 @@
}
}
}
- attributeMap = CollectionsExt.toCaseInsensitiveNameMap(attributes, NAME_LOCALE);
+ attributeMap = CollectionsExt.toCaseInsensitiveNameMap(attributes, Decoder.DATA_LOCALE);
attributeNames = attributeNames(attributes, attributeMap);
if (variables != null) {
this.variables = variables;
@@ -326,7 +320,7 @@
final E e = elements[index];
return new AbstractMap.SimpleImmutableEntry<>(e.getName(), e);
}
- }, NAME_LOCALE);
+ }, Decoder.DATA_LOCALE);
}
/**
@@ -631,7 +625,7 @@
default: throw malformedHeader();
}
}
- final Map<String,Object> map = CollectionsExt.toCaseInsensitiveNameMap(attributes, NAME_LOCALE);
+ final Map<String,Object> map = CollectionsExt.toCaseInsensitiveNameMap(attributes, Decoder.DATA_LOCALE);
variables[j] = new VariableInfo(this, input, name, varDims, map, attributeNames(attributes, map),
DataType.valueOf(input.readInt()), input.readInt(), readOffset());
}
@@ -727,7 +721,7 @@
protected Dimension findDimension(final String dimName) {
DimensionInfo dim = dimensionMap.get(dimName); // Give precedence to exact match before to ignore case.
if (dim == null) {
- final String lower = dimName.toLowerCase(ChannelDecoder.NAME_LOCALE);
+ final String lower = dimName.toLowerCase(Decoder.DATA_LOCALE);
if (lower != dimName) { // Identity comparison is okay here.
dim = dimensionMap.get(lower);
}
@@ -744,7 +738,7 @@
private VariableInfo findVariableInfo(final String name) {
VariableInfo v = variableMap.get(name);
if (v == null && name != null) {
- final String lower = name.toLowerCase(NAME_LOCALE);
+ final String lower = name.toLowerCase(Decoder.DATA_LOCALE);
// Identity comparison is ok since following check is only an optimization for a common case.
if (lower != name) {
v = variableMap.get(lower);
@@ -807,7 +801,7 @@
* Identity comparisons performed between String instances below are okay since they
* are only optimizations for skipping calls to Map.get(Object) in common cases.
*/
- final String lowerCase = mappedName.toLowerCase(NAME_LOCALE);
+ final String lowerCase = mappedName.toLowerCase(DATA_LOCALE);
if (lowerCase != mappedName) {
value = attributeMap.get(lowerCase);
if (value != null) return value;
@@ -866,11 +860,11 @@
* @return {@inheritDoc}
*/
@Override
- public Date dateValue(final String name) {
+ public Temporal dateValue(final String name) {
final Object value = findAttribute(name);
if (value instanceof CharSequence) try {
- return StandardDateFormat.toDate(StandardDateFormat.FORMAT.parse((CharSequence) value));
- } catch (DateTimeException | ArithmeticException e) {
+ return StandardDateFormat.parseBest((CharSequence) value);
+ } catch (RuntimeException e) {
listeners.warning(e);
}
return null;
@@ -884,16 +878,16 @@
* @return the converted values. May contain {@code null} elements.
*/
@Override
- public Date[] numberToDate(final String symbol, final Number... values) {
- final Date[] dates = new Date[values.length];
+ public Temporal[] numberToDate(final String symbol, final Number... values) {
+ final var dates = new Instant[values.length];
final Matcher parts = Variable.TIME_UNIT_PATTERN.matcher(symbol);
if (parts.matches()) try {
- final UnitConverter converter = Units.valueOf(parts.group(1)).getConverterToAny(Units.MILLISECOND);
- final long epoch = StandardDateFormat.toDate(StandardDateFormat.FORMAT.parse(parts.group(2))).getTime();
+ final UnitConverter converter = Units.valueOf(parts.group(1)).getConverterToAny(Units.SECOND);
+ final Instant epoch = StandardDateFormat.parseInstantUTC(parts.group(2));
for (int i=0; i<values.length; i++) {
final Number value = values[i];
if (value != null) {
- dates[i] = new Date(epoch + Math.round(converter.convert(value.doubleValue())));
+ dates[i] = TemporalDate.addSeconds(epoch, converter.convert(value.doubleValue()));
}
}
} catch (IncommensurableException | MeasurementParseException | DateTimeException | ArithmeticException e) {
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/ucar/DecoderWrapper.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/ucar/DecoderWrapper.java
index d64e8e6..381d8b1 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/ucar/DecoderWrapper.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/ucar/DecoderWrapper.java
@@ -18,11 +18,12 @@
import java.io.File;
import java.io.IOException;
-import java.util.Date;
import java.util.Set;
import java.util.List;
import java.util.Formatter;
import java.util.Collection;
+import java.time.Instant;
+import java.time.temporal.Temporal;
import ucar.nc2.Group;
import ucar.nc2.Attribute;
import ucar.nc2.NetcdfFile;
@@ -318,7 +319,7 @@
* @return the attribute value, or {@code null} if none or unparsable or if the given name was null.
*/
@Override
- public Date dateValue(final String name) {
+ public Temporal dateValue(final String name) {
if (name != null) {
for (final Group group : groups) {
final Attribute attribute = findAttribute(group, name);
@@ -332,7 +333,7 @@
listeners.warning(e);
continue;
}
- return new Date(date.getMillis());
+ return Instant.ofEpochMilli(date.getMillis());
}
}
}
@@ -348,8 +349,8 @@
* @return the converted values. May contains {@code null} elements.
*/
@Override
- public Date[] numberToDate(final String symbol, final Number... values) {
- final Date[] dates = new Date[values.length];
+ public Temporal[] numberToDate(final String symbol, final Number... values) {
+ final var dates = new Instant[values.length];
final DateUnit unit;
try {
unit = new DateUnit(symbol);
@@ -360,7 +361,7 @@
for (int i=0; i<values.length; i++) {
final Number value = values[i];
if (value != null) {
- dates[i] = unit.makeDate(value.doubleValue());
+ dates[i] = unit.makeDate(value.doubleValue()).toInstant();
}
}
return dates;
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/base/DecoderTest.java b/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/base/DecoderTest.java
index fb88162..cc73129 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/base/DecoderTest.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/base/DecoderTest.java
@@ -16,7 +16,7 @@
*/
package org.apache.sis.storage.netcdf.base;
-import java.util.Date;
+import java.time.Instant;
import java.io.IOException;
import org.apache.sis.storage.DataStoreException;
import static org.apache.sis.storage.netcdf.AttributeNames.*;
@@ -24,7 +24,6 @@
// Test dependencies
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
-import static org.apache.sis.test.TestUtilities.date;
/**
@@ -85,9 +84,9 @@
@Test
public void testDateValue() throws IOException, DataStoreException {
selectDataset(TestData.NETCDF_2D_GEOGRAPHIC);
- assertAttributeEquals(date("2005-09-22 00:00:00"), DATE_CREATED);
- assertAttributeEquals(date("2018-05-15 13:00:00"), DATE_MODIFIED);
- assertAttributeEquals((Date) null, DATE_ISSUED);
+ assertAttributeEquals(Instant.parse("2005-09-22T00:00:00Z"), DATE_CREATED);
+ assertAttributeEquals(Instant.parse("2018-05-15T13:00:00Z"), DATE_MODIFIED);
+ assertAttributeEquals((Instant) null, DATE_ISSUED);
}
/**
@@ -99,14 +98,14 @@
@Test
public void testNumberToDate() throws IOException, DataStoreException {
final Decoder decoder = selectDataset(TestData.NETCDF_2D_GEOGRAPHIC);
- assertArrayEquals(new Date[] {
- date("2005-09-22 00:00:00")
+ assertArrayEquals(new Instant[] {
+ Instant.parse("2005-09-22T00:00:00Z")
}, decoder.numberToDate("hours since 1992-1-1", 120312));
- assertArrayEquals(new Date[] {
- date("1970-01-09 18:00:00"),
- date("1969-12-29 06:00:00"),
- date("1993-04-10 00:00:00")
+ assertArrayEquals(new Instant[] {
+ Instant.parse("1970-01-09T18:00:00Z"),
+ Instant.parse("1969-12-29T06:00:00Z"),
+ Instant.parse("1993-04-10T00:00:00Z")
}, decoder.numberToDate("days since 1970-01-01T00:00:00Z", 8.75, -2.75, 8500));
}
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/base/TestCase.java b/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/base/TestCase.java
index 892938e..d5ae778 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/base/TestCase.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/test/org/apache/sis/storage/netcdf/base/TestCase.java
@@ -16,9 +16,10 @@
*/
package org.apache.sis.storage.netcdf.base;
-import java.util.Date;
import java.util.EnumMap;
import java.util.Iterator;
+import java.time.Instant;
+import java.time.ZoneOffset;
import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException;
import ucar.nc2.NetcdfFiles;
@@ -27,10 +28,10 @@
import ucar.nc2.dataset.NetcdfDataset;
import org.apache.sis.storage.AbstractResource;
import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.storage.DataStoreMock;
-import org.apache.sis.storage.netcdf.ucar.DecoderWrapper;
-import org.apache.sis.setup.GeometryLibrary;
import org.apache.sis.storage.event.StoreListeners;
+import org.apache.sis.storage.netcdf.ucar.DecoderWrapper;
+import org.apache.sis.util.privy.TemporalDate;
+import org.apache.sis.setup.GeometryLibrary;
// Test dependencies
import org.junit.jupiter.api.AfterAll;
@@ -39,6 +40,7 @@
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
+import org.apache.sis.storage.DataStoreMock;
/**
@@ -259,7 +261,7 @@
* @param attributeName the name of the attribute to test.
* @throws IOException if an error occurred while reading the netCDF file.
*/
- protected final void assertAttributeEquals(final Date expected, final String attributeName) throws IOException {
- assertEquals(expected, decoder.dateValue(attributeName), attributeName);
+ protected final void assertAttributeEquals(final Instant expected, final String attributeName) throws IOException {
+ assertEquals(expected, TemporalDate.toInstant(decoder.dateValue(attributeName), ZoneOffset.UTC), attributeName);
}
}
diff --git a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/ValueGetter.java b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/ValueGetter.java
index ec94830..b1158d1 100644
--- a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/ValueGetter.java
+++ b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/ValueGetter.java
@@ -33,7 +33,7 @@
import java.math.BigDecimal;
import org.apache.sis.math.Vector;
import org.apache.sis.util.Numbers;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
import org.apache.sis.util.privy.UnmodifiableArrayList;
@@ -361,8 +361,8 @@
* `Time.toLocalTime()` does not use sub-second precision.
* However, some databases provide millisecond precision.
*/
- final int milli = (int) (time.getTime() % StandardDateFormat.MILLIS_PER_SECOND);
- return time.toLocalTime().withNano(milli * StandardDateFormat.NANOS_PER_MILLISECOND);
+ final int milli = (int) (time.getTime() % Constants.MILLIS_PER_SECOND);
+ return time.toLocalTime().withNano(milli * Constants.NANOS_PER_MILLISECOND);
}
}
@@ -440,8 +440,8 @@
final Time time = source.getTime(columnIndex);
if (time == null) return null;
final int offsetMinute = -time.getTimezoneOffset();
- final int milli = (int) (time.getTime() % StandardDateFormat.MILLIS_PER_SECOND);
- return time.toLocalTime().withNano(milli * StandardDateFormat.NANOS_PER_MILLISECOND)
+ final int milli = (int) (time.getTime() % Constants.MILLIS_PER_SECOND);
+ return time.toLocalTime().withNano(milli * Constants.NANOS_PER_MILLISECOND)
.atOffset(ZoneOffset.ofHoursMinutes(offsetMinute / 60, offsetMinute % 60));
}
}
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 1b73721..ca5b904 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
@@ -371,7 +371,7 @@
*/
protected final Date getElementAsDate() throws XMLStreamException {
final String text = getElementText();
- return (text != null) ? StandardDateFormat.toDate(StandardDateFormat.FORMAT.parse(text)) : null;
+ return (text == null) ? null : Date.from(StandardDateFormat.parseInstantUTC(text));
}
/**
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/AbstractGridCoverageResource.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/AbstractGridCoverageResource.java
index 46a0e93..a0abd3b 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/AbstractGridCoverageResource.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/AbstractGridCoverageResource.java
@@ -37,7 +37,7 @@
import org.apache.sis.measure.AngleFormat;
import org.apache.sis.util.logging.PerformanceLevel;
import org.apache.sis.io.stream.IOUtilities;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
import org.apache.sis.storage.base.MetadataBuilder;
import org.apache.sis.storage.internal.Resources;
@@ -203,7 +203,7 @@
final Locale locale = listeners.getLocale();
final Object[] parameters = new Object[6];
parameters[0] = IOUtilities.filename(file != null ? file : listeners.getSourceName());
- parameters[5] = nanos / (double) StandardDateFormat.NANOS_PER_SECOND;
+ parameters[5] = nanos / (double) Constants.NANOS_PER_SECOND;
domain.getGeographicExtent().ifPresentOrElse((box) -> {
final AngleFormat f = new AngleFormat(locale);
double min = box.getSouthBoundLatitude();
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/LegalSymbols.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/LegalSymbols.java
index 8450ecd..93dbbdb 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/LegalSymbols.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/LegalSymbols.java
@@ -27,7 +27,7 @@
import org.apache.sis.metadata.iso.citation.DefaultCitation;
import org.apache.sis.metadata.iso.citation.DefaultCitationDate;
import org.apache.sis.metadata.iso.constraint.DefaultLegalConstraints;
-import static org.apache.sis.util.privy.StandardDateFormat.MILLISECONDS_PER_DAY;
+import static org.apache.sis.util.privy.Constants.MILLISECONDS_PER_DAY;
// Specific to the main and geoapi-3.1 branches:
import org.apache.sis.metadata.iso.citation.DefaultResponsibleParty;
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 82c9f69..a441828 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
@@ -71,7 +71,7 @@
import org.apache.sis.util.iso.Types;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.privy.CollectionsExt;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
import org.apache.sis.util.privy.Strings;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.metadata.ModifiableMetadata;
@@ -1125,9 +1125,9 @@
* @param type the type of the date to add, or {@code null} if none (not legal but tolerated).
* @param scope whether the date applies to data, to metadata or to both.
*
- * @see #addAcquisitionTime(Date)
+ * @see #addAcquisitionTime(Temporal)
*/
- public final void addCitationDate(final Date date, final DateType type, final Scope scope) {
+ public final void addCitationDate(final Temporal date, final DateType type, final Scope scope) {
if (date != null) {
final var cd = new DefaultCitationDate(date, type);
if (scope != Scope.RESOURCE) addEarliest(metadata().getDateInfo(), cd, type);
@@ -1800,25 +1800,10 @@
*
* @param startTime when the data begins, or {@code null} if unbounded.
* @param endTime when the data ends, or {@code null} if unbounded.
+ *
+ * @see #addAcquisitionTime(Temporal)
*/
public final void addTemporalExtent(final Temporal startTime, final Temporal endTime) {
- addTemporalExtent(StandardDateFormat.toDate(startTime), StandardDateFormat.toDate(endTime));
- }
-
- /**
- * Adds a temporal extent covered by the data.
- * Storage location is:
- *
- * <ul>
- * <li>{@code metadata/identificationInfo/extent/temporalElement}</li>
- * </ul>
- *
- * @param startTime when the data begins, or {@code null} if unbounded.
- * @param endTime when the data ends, or {@code null} if unbounded.
- *
- * @see #addAcquisitionTime(Date)
- */
- public final void addTemporalExtent(final Date startTime, final Date endTime) {
if (startTime != null || endTime != null) {
final var t = new DefaultTemporalExtent();
t.setBounds(startTime, endTime);
@@ -2051,7 +2036,7 @@
public final void addTemporalResolution(final double duration) {
if (Double.isFinite(duration)) {
addIfNotPresent(identification().getTemporalResolutions(),
- Duration.ofMillis(Math.round(duration * StandardDateFormat.MILLISECONDS_PER_DAY)));
+ Duration.ofNanos(Math.round(duration * Constants.NANOSECONDS_PER_DAY)));
}
}
@@ -2701,9 +2686,9 @@
*
* @param time the acquisition time, or {@code null} for no-operation.
*
- * @see #addTemporalExtent(Date, Date)
+ * @see #addTemporalExtent(Temporal, Temporal)
*/
- public final void addAcquisitionTime(final Date time) {
+ public final void addAcquisitionTime(final Temporal time) {
if (time != null) {
final var event = new DefaultEvent();
event.setContext(Context.ACQUISITION);
@@ -2729,15 +2714,15 @@
* @param endTime end time, or {@code null} if unknown.
*/
public final void addAcquisitionTime(final Instant startTime, final Instant endTime) {
- final Date time;
+ final Temporal time;
if (startTime == null) {
if (endTime == null) return;
- time = Date.from(endTime);
+ time = endTime;
} else if (endTime == null) {
- time = Date.from(startTime);
+ time = startTime;
} else {
// Divide by 2 before to add in order to avoid overflow.
- time = new Date((startTime.toEpochMilli() >> 1) + (endTime.toEpochMilli() >> 1));
+ time = Instant.ofEpochMilli((startTime.toEpochMilli() >> 1) + (endTime.toEpochMilli() >> 1));
}
addAcquisitionTime(time);
}
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java
index 37e92b8..1b818fb 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java
@@ -19,7 +19,6 @@
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Date;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Stream;
@@ -448,7 +447,7 @@
temporal = TimeEncoding.DEFAULT.crs();
timeEncoding = TimeEncoding.ABSOLUTE;
} else {
- temporal = builder.createTemporalCRS(Date.from(startTime), timeUnit);
+ temporal = builder.createTemporalCRS(startTime, timeUnit);
timeEncoding = new TimeEncoding(temporal.getDatum(), timeUnit);
}
components[count++] = temporal;
@@ -480,8 +479,8 @@
envelope.setRange(i, lowerCorner[i], upperCorner[i]);
}
if (startTime != null) {
- envelope.setRange(spatialDimensionCount, timeEncoding.toCRS(startTime.toEpochMilli()),
- (endTime == null) ? Double.NaN : timeEncoding.toCRS(endTime.toEpochMilli()));
+ envelope.setRange(spatialDimensionCount, timeEncoding.toCRS(startTime),
+ (endTime == null) ? Double.NaN : timeEncoding.toCRS(endTime));
}
this.spatialDimensionCount = (short) spatialDimensionCount;
return envelope;
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/TimeEncoding.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/TimeEncoding.java
index 3458095..8fe13bc 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/TimeEncoding.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/TimeEncoding.java
@@ -17,11 +17,13 @@
package org.apache.sis.storage.csv;
import java.time.Instant;
+import java.time.temporal.ChronoUnit;
import javax.measure.Unit;
import javax.measure.quantity.Time;
import org.opengis.referencing.datum.TemporalDatum;
import org.apache.sis.converter.SurjectiveConverter;
import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.TemporalDate;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.measure.Units;
@@ -49,12 +51,12 @@
};
/**
- * Date of value zero on the time axis, in milliseconds since January 1st 1970 at midnight UTC.
+ * Date of value zero on the time axis.
*/
- private final long origin;
+ private final Instant origin;
/**
- * Number of milliseconds between two consecutive integer values on the time axis.
+ * Number of seconds between two consecutive integer values on the time axis.
*/
private final double interval;
@@ -62,8 +64,8 @@
* Creates a new time encoding.
*/
TimeEncoding(final TemporalDatum datum, final Unit<Time> unit) {
- this.origin = datum.getOrigin().getTime();
- this.interval = unit.getConverterTo(Units.MILLISECOND).convert(1);
+ this.origin = TemporalDate.toInstant(datum.getOrigin());
+ this.interval = unit.getConverterTo(Units.SECOND).convert(1);
}
/**
@@ -90,23 +92,16 @@
*/
@Override
public Instant apply(final String time) {
- final double value = Double.parseDouble(time) * interval;
- final long millis = Math.round(value);
- return Instant.ofEpochMilli(millis + origin)
- .plusNanos(Math.round((value - millis) * StandardDateFormat.NANOS_PER_MILLISECOND));
- /*
- * Performance note: the call to .plusNano(…) will usually return the same 'Instant' instance
- * (without creating new object) since the time granularity is rarely finer than milliseconds.
- */
+ return TemporalDate.addSeconds(origin, Double.parseDouble(time) * interval);
}
/**
* Converts the given timestamp to the values used in the temporal coordinate reference system.
*
- * @param time number of milliseconds elapsed since January 1st, 1970 midnight UTC.
+ * @param time instant to convert.
* @return the value to use with the temporal coordinate reference system.
*/
- final double toCRS(final long time) {
- return (time - origin) / interval;
+ final double toCRS(final Instant time) {
+ return origin.until(time, ChronoUnit.SECONDS) / interval;
}
}
diff --git a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/test/CoverageReadConsistency.java b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/test/CoverageReadConsistency.java
index a5744ff..3003ead 100644
--- a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/test/CoverageReadConsistency.java
+++ b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/test/CoverageReadConsistency.java
@@ -33,7 +33,7 @@
import org.apache.sis.storage.RasterLoadingStrategy;
import org.apache.sis.util.Workaround;
import org.apache.sis.util.ArraysExt;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
import org.apache.sis.util.privy.Numerics;
import org.apache.sis.image.PixelIterator;
import org.apache.sis.math.Statistics;
@@ -463,7 +463,7 @@
break;
}
if (durations != null) {
- durations.accept((System.nanoTime() - startTime) / (double) StandardDateFormat.NANOS_PER_MILLISECOND);
+ durations.accept((System.nanoTime() - startTime) / (double) Constants.NANOS_PER_MILLISECOND);
}
}
/*
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 d45660d..5d912fa 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
@@ -48,7 +48,7 @@
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.privy.MetadataServices;
import org.apache.sis.util.privy.LocalizedParseException;
-import static org.apache.sis.util.privy.StandardDateFormat.UTC;
+import static org.apache.sis.util.privy.Constants.UTC;
/**
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 6bf6a90..30f8441 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
@@ -43,7 +43,7 @@
import org.apache.sis.util.UnconvertibleObjectException;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.privy.LocalizedParseException;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.TemporalDate;
import org.apache.sis.util.privy.Numerics;
@@ -362,8 +362,8 @@
elementFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale);
unitFormat = null;
} else if (Temporal.class.isAssignableFrom(elementType)) {
- final FormatStyle dateStyle = StandardDateFormat.hasDateFields(elementType) ? FormatStyle.SHORT : null;
- final FormatStyle timeStyle = StandardDateFormat.hasTimeFields(elementType) ? FormatStyle.SHORT : null;
+ final FormatStyle dateStyle = TemporalDate.hasDateFields(elementType) ? FormatStyle.SHORT : null;
+ final FormatStyle timeStyle = TemporalDate.hasTimeFields(elementType) ? FormatStyle.SHORT : null;
elementFormat = new DateTimeFormatterBuilder().appendLocalized(dateStyle, timeStyle).toFormatter(locale).toFormat();
unitFormat = null;
} else {
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/UnitNames.properties b/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/UnitNames.properties
index 7cf0da8..ade411d 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/UnitNames.properties
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/UnitNames.properties
@@ -47,6 +47,7 @@
ms=millisecond
N=newton
nm=nanometre
+ns=nanosecond
Pa=pascal
ppm=parts per million
psu=practical salinity unit
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/UnitNames_fr.properties b/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/UnitNames_fr.properties
index bb1a4cf..ceb0cce 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/UnitNames_fr.properties
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/UnitNames_fr.properties
@@ -27,6 +27,7 @@
mm=millim\u00e8tre
ms=milliseconde
nm=nanom\u00e8tre
+ns=nanoseconde
ppm=parties par million
rad\u2215s=radians par seconde
s=seconde
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/Units.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/Units.java
index 68954b7..a5405d3 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/Units.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/measure/Units.java
@@ -35,6 +35,8 @@
import static org.apache.sis.measure.UnitRegistry.IMPERIAL;
import static org.apache.sis.measure.UnitRegistry.OTHER;
import static org.apache.sis.measure.UnitRegistry.PREFIXABLE;
+import static org.apache.sis.util.privy.Constants.SECONDS_PER_DAY;
+import static org.apache.sis.util.privy.Constants.MILLIS_PER_TROPICAL_YEAR;
/**
@@ -56,7 +58,7 @@
* <tr><td style="padding-top:15px" colspan="4"><b>Fundamental:</b></td></tr>
* <tr><td>{@link Length}</td> <td>(L)</td> <td>{@link #METRE}</td> <td>{@link #CENTIMETRE}, {@link #KILOMETRE}, {@link #NAUTICAL_MILE}, {@link #STATUTE_MILE}, {@link #FOOT}</td></tr>
* <tr><td>{@link Mass}</td> <td>(M)</td> <td>{@link #KILOGRAM}</td> <td></td></tr>
- * <tr><td>{@link Time}</td> <td>(T)</td> <td>{@link #SECOND}</td> <td>{@link #MILLISECOND}, {@link #MINUTE}, {@link #HOUR}, {@link #DAY}, {@link #WEEK}, {@link #TROPICAL_YEAR}</td></tr>
+ * <tr><td>{@link Time}</td> <td>(T)</td> <td>{@link #SECOND}</td> <td>{@link #NANOSECOND}, {@link #MILLISECOND}, {@link #MINUTE}, {@link #HOUR}, {@link #DAY}, {@link #WEEK}, {@link #TROPICAL_YEAR}</td></tr>
* <tr><td>{@link ElectricCurrent}</td> <td>(I)</td> <td>{@link #AMPERE}</td> <td></td></tr>
* <tr><td>{@link Temperature}</td> <td>(Θ)</td> <td>{@link #KELVIN}</td> <td>{@link #CELSIUS}, {@link #FAHRENHEIT}</td></tr>
* <tr><td>{@link AmountOfSubstance}</td> <td>(N)</td> <td>{@link #MOLE}</td> <td></td></tr>
@@ -447,6 +449,25 @@
public static final Unit<Angle> GRAD;
/**
+ * Unit of measurement defined as 10<sup>-9</sup> seconds (1 ms).
+ * This unit is useful for inter-operability with various methods from the standard Java library.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #SECOND}
+ * and the unlocalized name is “nanosecond”.
+ *
+ * <table class="compact" style="margin-left:30px; line-height:1.25">
+ * <caption>Related units</caption>
+ * <tr><td>SI time units:</td> <td style="word-spacing:1em"><u>{@code NANOSECOND}</u>, {@link #MILLISECOND}, <b>{@link #SECOND}</b>.</td></tr>
+ * <tr><td>Non-SI units:</td> <td style="word-spacing:1em">{@link #MINUTE}, {@link #HOUR}, {@link #DAY}, {@link #WEEK}, {@link #TROPICAL_YEAR}.</td></tr>
+ * <tr><td>Derived units:</td> <td style="word-spacing:1em">{@link #METRES_PER_SECOND}, {@link #HERTZ}, {@link #BECQUEREL}.</td></tr>
+ * </table>
+ *
+ * @see java.util.concurrent.TimeUnit#NANOSECONDS
+ *
+ * @since 1.5
+ */
+ public static final Unit<Time> NANOSECOND;
+
+ /**
* Unit of measurement defined as 10<sup>-3</sup> seconds (1 ms).
* This unit is useful for inter-operability with various methods from the standard Java library.
* The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #SECOND}
@@ -454,7 +475,7 @@
*
* <table class="compact" style="margin-left:30px; line-height:1.25">
* <caption>Related units</caption>
- * <tr><td>SI time units:</td> <td style="word-spacing:1em"><u>{@code MILLISECOND}</u>, <b>{@link #SECOND}</b>.</td></tr>
+ * <tr><td>SI time units:</td> <td style="word-spacing:1em"><u>{@link #NANOSECOND}, {@code MILLISECOND}</u>, <b>{@link #SECOND}</b>.</td></tr>
* <tr><td>Non-SI units:</td> <td style="word-spacing:1em">{@link #MINUTE}, {@link #HOUR}, {@link #DAY}, {@link #WEEK}, {@link #TROPICAL_YEAR}.</td></tr>
* <tr><td>Derived units:</td> <td style="word-spacing:1em">{@link #METRES_PER_SECOND}, {@link #HERTZ}, {@link #BECQUEREL}.</td></tr>
* </table>
@@ -472,7 +493,7 @@
*
* <table class="compact" style="margin-left:30px; line-height:1.25">
* <caption>Related units</caption>
- * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #MILLISECOND}, <u><b>{@link #SECOND}</b></u>.</td></tr>
+ * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #NANOSECOND}, {@link #MILLISECOND}, <u><b>{@link #SECOND}</b></u>.</td></tr>
* <tr><td>Non-SI units:</td> <td style="word-spacing:1em">{@link #MINUTE}, {@link #HOUR}, {@link #DAY}, {@link #WEEK}, {@link #TROPICAL_YEAR}.</td></tr>
* <tr><td>Derived units:</td> <td style="word-spacing:1em">{@link #METRES_PER_SECOND}, {@link #HERTZ}, {@link #BECQUEREL}.</td></tr>
* </table>
@@ -488,7 +509,7 @@
*
* <table class="compact" style="margin-left:30px; line-height:1.25">
* <caption>Related units</caption>
- * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #MILLISECOND}, <b>{@link #SECOND}</b>.</td></tr>
+ * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #NANOSECOND}, {@link #MILLISECOND}, <b>{@link #SECOND}</b>.</td></tr>
* <tr><td>Non-SI units:</td> <td style="word-spacing:1em"><u>{@code MINUTE}</u>, {@link #HOUR}, {@link #DAY}, {@link #WEEK}, {@link #TROPICAL_YEAR}.</td></tr>
* <tr><td>Derived units:</td> <td style="word-spacing:1em">{@link #METRES_PER_SECOND}, {@link #HERTZ}, {@link #BECQUEREL}.</td></tr>
* </table>
@@ -504,7 +525,7 @@
*
* <table class="compact" style="margin-left:30px; line-height:1.25">
* <caption>Related units</caption>
- * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #MILLISECOND}, <b>{@link #SECOND}</b>.</td></tr>
+ * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #NANOSECOND}, {@link #MILLISECOND}, <b>{@link #SECOND}</b>.</td></tr>
* <tr><td>Non-SI units:</td> <td style="word-spacing:1em">{@link #MINUTE}, <u>{@code HOUR}</u>, {@link #DAY}, {@link #WEEK}, {@link #TROPICAL_YEAR}.</td></tr>
* <tr><td>Derived units:</td> <td style="word-spacing:1em">{@link #KILOMETRES_PER_HOUR}, {@link #HERTZ}, {@link #BECQUEREL}.</td></tr>
* </table>
@@ -520,7 +541,7 @@
*
* <table class="compact" style="margin-left:30px; line-height:1.25">
* <caption>Related units</caption>
- * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #MILLISECOND}, <b>{@link #SECOND}</b>.</td></tr>
+ * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #NANOSECOND}, {@link #MILLISECOND}, <b>{@link #SECOND}</b>.</td></tr>
* <tr><td>Non-SI units:</td> <td style="word-spacing:1em">{@link #MINUTE}, {@link #HOUR}, <u>{@code DAY}</u>, {@link #WEEK}, {@link #TROPICAL_YEAR}.</td></tr>
* <tr><td>Derived units:</td> <td style="word-spacing:1em">{@link #KILOMETRES_PER_HOUR}, {@link #HERTZ}, {@link #BECQUEREL}.</td></tr>
* </table>
@@ -536,7 +557,7 @@
*
* <table class="compact" style="margin-left:30px; line-height:1.25">
* <caption>Related units</caption>
- * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #MILLISECOND}, <b>{@link #SECOND}</b>.</td></tr>
+ * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #NANOSECOND}, {@link #MILLISECOND}, <b>{@link #SECOND}</b>.</td></tr>
* <tr><td>Non-SI units:</td> <td style="word-spacing:1em">{@link #MINUTE}, {@link #HOUR}, {@link #DAY}, <u>{@link #WEEK}</u>, {@link #TROPICAL_YEAR}.</td></tr>
* <tr><td>Derived units:</td> <td style="word-spacing:1em">{@link #KILOMETRES_PER_HOUR}, {@link #HERTZ}, {@link #BECQUEREL}.</td></tr>
* </table>
@@ -554,7 +575,7 @@
*
* <table class="compact" style="margin-left:30px; line-height:1.25">
* <caption>Related units</caption>
- * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #MILLISECOND}, <b>{@link #SECOND}</b>.</td></tr>
+ * <tr><td>SI time units:</td> <td style="word-spacing:1em">{@link #NANOSECOND}, {@link #MILLISECOND}, <b>{@link #SECOND}</b>.</td></tr>
* <tr><td>Non-SI units:</td> <td style="word-spacing:1em">{@link #MINUTE}, {@link #HOUR}, {@link #DAY}, {@link #WEEK}, <u>{@code TROPICAL_YEAR}</u>.</td></tr>
* <tr><td>Derived units:</td> <td style="word-spacing:1em">{@link #KILOMETRES_PER_HOUR}, {@link #HERTZ}, {@link #BECQUEREL}.</td></tr>
* </table>
@@ -1256,12 +1277,13 @@
*/
s.related(5);
SECOND = s;
- MILLISECOND = add(s, milli, "ms", SI, (short) 0);
- MINUTE = add(s, LinearConverter.scale( 60, 1), "min", ACCEPTED, (short) 0);
- HOUR = add(s, LinearConverter.scale( 60*60, 1), "h", ACCEPTED, (short) 0);
- DAY = add(s, LinearConverter.scale( 24*60*60, 1), "d", ACCEPTED, (short) 0);
- WEEK = add(s, LinearConverter.scale( 7*24*60*60, 1), "wk", OTHER, (short) 0);
- TROPICAL_YEAR = add(s, LinearConverter.scale(31556925445.0, 1000), "a", OTHER, (short) 1029);
+ NANOSECOND = add(s, nano, "ns", SI, (short) 0);
+ MILLISECOND = add(s, milli, "ms", SI, (short) 0);
+ MINUTE = add(s, LinearConverter.scale( 60, 1), "min", ACCEPTED, (short) 0);
+ HOUR = add(s, LinearConverter.scale( 60*60, 1), "h", ACCEPTED, (short) 0);
+ DAY = add(s, LinearConverter.scale( SECONDS_PER_DAY, 1), "d", ACCEPTED, (short) 0);
+ WEEK = add(s, LinearConverter.scale( 7*SECONDS_PER_DAY, 1), "wk", OTHER, (short) 0);
+ TROPICAL_YEAR = add(s, LinearConverter.scale(MILLIS_PER_TROPICAL_YEAR, 1000), "a", OTHER, (short) 1029);
/*
* All Unit<Speed>, Unit<Acceleration>, Unit<AngularVelocity> and Unit<ScaleRateOfChange>.
* The `unityPerSecond` unit is not added to the registry because it is specific to the EPSG database,
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/pending/jdk/JDK23.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/pending/jdk/JDK23.java
new file mode 100644
index 0000000..a29acac
--- /dev/null
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/pending/jdk/JDK23.java
@@ -0,0 +1,47 @@
+/*
+ * 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.pending.jdk;
+
+import java.time.Duration;
+import java.time.Instant;
+
+
+/**
+ * Place holder for some functionalities defined in a JDK more recent than Java 11.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public final class JDK23 {
+ /**
+ * Do not allow instantiation of this class.
+ */
+ private JDK23() {
+ }
+
+ /**
+ * Placeholder for {@code Instant.until(Instant)}.
+ * The method provided in Java 23 is optimized compared to the more generic {@code Duration.between} method.
+ * The purpose of this placeholder is only for remembering to do the substitution.
+ *
+ * @param start the start time.
+ * @param endExclusive the end time.
+ * @return duration between the two times.
+ */
+ public static Duration until(Instant start, Instant endExclusive) {
+ return Duration.between(start, endExclusive);
+ }
+}
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/About.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/About.java
index 30b539f..f004670 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/About.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/About.java
@@ -59,7 +59,7 @@
import org.apache.sis.system.DataDirectory;
import static org.apache.sis.util.collection.TableColumn.NAME;
import static org.apache.sis.util.collection.TableColumn.VALUE_AS_TEXT;
-import static org.apache.sis.util.privy.StandardDateFormat.UTC;
+import static org.apache.sis.util.privy.Constants.UTC;
/**
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/logging/MonolineFormatter.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/logging/MonolineFormatter.java
index 6cb9e9d..976029c 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/logging/MonolineFormatter.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/logging/MonolineFormatter.java
@@ -42,7 +42,7 @@
import org.apache.sis.util.internal.AutoMessageFormat;
import org.apache.sis.io.IO;
import org.apache.sis.io.LineAppender;
-import static org.apache.sis.util.privy.StandardDateFormat.UTC;
+import static org.apache.sis.util.privy.Constants.UTC;
/**
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/Constants.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/Constants.java
index f4a975c..eb93271 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/Constants.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/Constants.java
@@ -50,6 +50,54 @@
public static final byte DEFAULT_INDENTATION = 2;
/**
+ * The length of a day in number of seconds.
+ * Can be casted to {@code float} with exact precision.
+ */
+ public static final int SECONDS_PER_DAY = 24*60*60;
+
+ /**
+ * The length of a day in number of milliseconds.
+ * Can be casted to {@code float} with exact precision.
+ */
+ public static final int MILLISECONDS_PER_DAY = SECONDS_PER_DAY * 1000;
+
+ /**
+ * The length of a day in number of nanoseconds.
+ */
+ public static final long NANOSECONDS_PER_DAY = MILLISECONDS_PER_DAY * (long) 1_000_000;
+
+ /**
+ * Number of milliseconds in one second.
+ * Can be casted to {@code float} with exact precision.
+ */
+ public static final int MILLIS_PER_SECOND = 1000;
+
+ /**
+ * Number of nanoseconds in one millisecond.
+ * Can be casted to {@code float} with exact precision.
+ */
+ public static final int NANOS_PER_MILLISECOND = 1000_000;
+
+ /**
+ * Number of nanoseconds in one second.
+ * Can be casted to {@code float} with exact precision.
+ */
+ public static final int NANOS_PER_SECOND = 1000_000_000;
+
+ /**
+ * Length of a year as defined by the International Union of Geological Sciences (IUGS), in milliseconds.
+ * This is the unit of measurement used in EPSG geodetic dataset (EPSG:1029).
+ */
+ public static final long MILLIS_PER_TROPICAL_YEAR = 31556925445L;
+
+ /**
+ * The {@value} timezone ID.
+ *
+ * @see java.time.ZoneOffset#UTC
+ */
+ public static final String UTC = "UTC";
+
+ /**
* The {@value} protocol.
*/
public static final String HTTP = "http", HTTPS = "https";
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/DoubleDouble.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/DoubleDouble.java
index 94efbb8..15f522b 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/DoubleDouble.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/DoubleDouble.java
@@ -17,6 +17,7 @@
package org.apache.sis.util.privy;
import java.util.Arrays;
+import java.time.Duration;
import java.math.BigInteger;
import java.math.BigDecimal;
import java.math.MathContext;
@@ -257,6 +258,16 @@
}
/**
+ * Returns an instance for the given duration in nanoseconds.
+ *
+ * @param value the duration to convert.
+ * @return the given duration, in nanoseconds.
+ */
+ public static DoubleDouble of(final Duration value) {
+ return of(value.getSeconds()).multiply(Constants.NANOS_PER_SECOND).add(value.getNano());
+ }
+
+ /**
* Returns an instance for the given integer.
*
* @param value the integer value to wrap in a {@code DoubleDouble}.
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/StandardDateFormat.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/StandardDateFormat.java
index 8df9765..6c4ee5e 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/StandardDateFormat.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/StandardDateFormat.java
@@ -27,14 +27,12 @@
import java.text.ParseException;
import java.time.DateTimeException;
import java.time.Instant;
-import java.time.LocalTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
import java.time.temporal.Temporal;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalQuery;
@@ -67,13 +65,6 @@
@SuppressWarnings("serial") // Not intended to be serialized.
public final class StandardDateFormat extends DateFormat {
/**
- * The {@value} timezone ID.
- *
- * @see ZoneOffset#UTC
- */
- public static final String UTC = "UTC";
-
- /**
* Midnight (00:00) UTC.
*/
private static final OffsetTime MIDNIGHT = OffsetTime.of(0, 0, 0, 0, ZoneOffset.UTC);
@@ -218,92 +209,6 @@
}
/**
- * The length of a day in number of milliseconds.
- * Can be casted to {@code float} with exact precision.
- */
- public static final int MILLISECONDS_PER_DAY = 24*60*60*1000;
-
- /**
- * Number of milliseconds in one second.
- * Can be casted to {@code float} with exact precision.
- */
- public static final int MILLIS_PER_SECOND = 1000;
-
- /**
- * Number of nanoseconds in one millisecond.
- * Can be casted to {@code float} with exact precision.
- */
- public static final int NANOS_PER_MILLISECOND = 1000_000;
-
- /**
- * Number of nanoseconds in one second.
- * Can be casted to {@code float} with exact precision.
- */
- public static final int NANOS_PER_SECOND = 1000_000_000;
-
- /**
- * Converts the given temporal object into a date.
- * The given temporal object is typically the value parsed by {@link #FORMAT}.
- *
- * @param temporal the temporal object to convert, or {@code null}.
- * @return the legacy date for the given temporal object, or {@code null} if the argument was null.
- * @throws DateTimeException if a value for the field cannot be obtained.
- * @throws ArithmeticException if the number of milliseconds is too large.
- */
- public static Date toDate(final TemporalAccessor temporal) {
- if (temporal == null) {
- return null;
- }
- long millis;
- if (temporal instanceof Instant) {
- millis = ((Instant) temporal).toEpochMilli();
- } else if (temporal.isSupported(ChronoField.INSTANT_SECONDS)) {
- millis = Math.multiplyExact(temporal.getLong(ChronoField.INSTANT_SECONDS), 1000);
- millis = Math.addExact(millis, temporal.getLong(ChronoField.NANO_OF_SECOND) / 1000000);
- } else {
- // Note that the timezone may be unknown here. We assume UTC.
- millis = Math.multiplyExact(temporal.getLong(ChronoField.EPOCH_DAY), MILLISECONDS_PER_DAY);
- if (temporal.isSupported(ChronoField.MILLI_OF_DAY)) {
- millis = Math.addExact(millis, temporal.getLong(ChronoField.MILLI_OF_DAY));
- }
- }
- return new Date(millis);
- }
-
- /**
- * Returns {@code true} if objects of the given class have day, month and hour fields.
- * This method is defined here for having a single class where to concentrate such heuristic rules.
- * Note that {@link Instant} does not have date fields.
- *
- * @param date class of object to test (may be {@code null}).
- * @return whether the given class is {@link LocalDate} or one of the classes with date + time.
- * This list may be expanded in future versions.
- */
- public static boolean hasDateFields(final Class<?> date) {
- return date == LocalDate.class
- || date == LocalDateTime.class
- || date == OffsetDateTime.class
- || date == ZonedDateTime.class;
- }
-
- /**
- * Returns {@code true} if objects of the given class have time fields.
- * This method is defined here for having a single class where to concentrate such heuristic rules.
- * Note that {@link Instant} does not have hour fields.
- *
- * @param date class of object to test (may be {@code null}).
- * @return whether the given class is {@link LocalTime}, {@link OffsetTime} or one of the classes with date + time.
- * This list may be expanded in future versions.
- */
- public static boolean hasTimeFields(final Class<?> date) {
- return date == LocalTime.class
- || date == OffsetTime.class
- || date == LocalDateTime.class
- || date == OffsetDateTime.class
- || date == ZonedDateTime.class;
- }
-
- /**
* The {@code java.time} parser and formatter. This is usually the {@link #FORMAT} instance
* unless a different locale or timezone has been specified.
*/
@@ -341,7 +246,7 @@
*/
public StandardDateFormat(final Locale locale, final TimeZone zone) {
this(locale);
- if (!UTC.equals(zone.getID())) {
+ if (!Constants.UTC.equals(zone.getID())) {
setTimeZone(zone);
}
}
@@ -375,14 +280,21 @@
}
/**
+ * Returns the zone, or UTC if unspecified.
+ */
+ private ZoneId getZone() {
+ final ZoneId zone = format.getZone();
+ return (zone != null) ? zone : ZoneOffset.UTC;
+ }
+
+ /**
* Returns the timezone used for formatting instants.
*
* @return the timezone.
*/
@Override
public final TimeZone getTimeZone() {
- final ZoneId zone = format.getZone();
- return TimeZone.getTimeZone(zone != null ? zone : ZoneOffset.UTC);
+ return TimeZone.getTimeZone(getZone());
}
/**
@@ -430,11 +342,7 @@
*/
@Override
public StringBuffer format(final Date date, final StringBuffer toAppendTo, final FieldPosition pos) {
- ZoneId zone = format.getZone();
- if (zone == null) {
- zone = ZoneOffset.UTC;
- }
- final LocalDateTime dt = LocalDateTime.ofInstant(date.toInstant(), zone);
+ final LocalDateTime dt = LocalDateTime.ofInstant(date.toInstant(), getZone());
TemporalAccessor value = dt;
if (dt.getHour() == 0 && dt.getMinute() == 0 && dt.getSecond() == 0 && dt.getNano() == 0) {
value = dt.toLocalDate();
@@ -454,7 +362,7 @@
@Override
public Date parse(final String text, final ParsePosition position) {
try {
- return toDate(format.parse(text, position));
+ return Date.from(TemporalDate.toInstant(format.parse(text, position), getZone()));
} catch (DateTimeException | ArithmeticException e) {
position.setErrorIndex(getErrorIndex(e, position));
return null;
@@ -471,8 +379,8 @@
@Override
public Date parse(final String text) throws ParseException {
try {
- return toDate(format.parse(toISO(text, 0, text.length())));
- } catch (DateTimeException | ArithmeticException e) {
+ return Date.from(TemporalDate.toInstant(format.parse(toISO(text, 0, text.length())), getZone()));
+ } catch (RuntimeException e) {
throw (ParseException) new ParseException(e.getLocalizedMessage(), getErrorIndex(e, null)).initCause(e);
}
}
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/TemporalDate.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/TemporalDate.java
new file mode 100644
index 0000000..ed081ca
--- /dev/null
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/privy/TemporalDate.java
@@ -0,0 +1,236 @@
+/*
+ * 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.util.privy;
+
+import java.util.Date;
+import java.time.DateTimeException;
+import java.time.Instant;
+import java.time.LocalTime;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.temporal.Temporal;
+import java.time.temporal.ChronoField;
+import java.time.temporal.TemporalAccessor;
+import java.time.chrono.ChronoZonedDateTime;
+import org.apache.sis.util.resources.Errors;
+
+
+/**
+ * A date which is wrapping a {@code java.time} temporal object.
+ * This is used for interoperability in a situation where we are mixing
+ * legacy API working on {@link Date} with newer API working on {@link Temporal}.
+ *
+ * <h2>Design note</h2>
+ * This class intentionally don't implement {@link Temporal} in order to force unwrapping
+ * if a temporal object is desired.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public final class TemporalDate extends Date { // Intentionally do not implement Temporal.
+ /**
+ * For cross-version compatibility.
+ */
+ private static final long serialVersionUID = 8239300258490556354L;
+
+ /**
+ * The temporal object wrapped by this date.
+ */
+ @SuppressWarnings("serial") // Most implementations are serializable.
+ private final Temporal temporal;
+
+ /**
+ * Creates a new date for the given instant.
+ *
+ * @param temporal the temporal object to wrap in a new date.
+ * @throws ArithmeticException if numeric overflow occurs.
+ */
+ private TemporalDate(final Instant temporal) {
+ super(temporal.toEpochMilli());
+ this.temporal = temporal;
+ }
+
+ /**
+ * Creates a new date for the given temporal.
+ *
+ * @param temporal the temporal object to wrap in a new date.
+ * @throws ArithmeticException if numeric overflow occurs.
+ */
+ private TemporalDate(final Temporal temporal) {
+ super(toInstant(temporal, ZoneOffset.UTC).toEpochMilli());
+ this.temporal = temporal;
+ }
+
+ /**
+ * Returns the given temporal object as a date.
+ * Used for interoperability in situations where old and new Java API are mixed.
+ *
+ * @param time the temporal object to return as a date, or {@code null}.
+ * @return the given temporal object as a date, or {@code null} if the given argument was null.
+ * @throws ArithmeticException if numeric overflow occurs.
+ */
+ public static Date toDate(final Temporal time) {
+ return (time == null) ? null : new TemporalDate(time);
+ }
+
+ /**
+ * Returns the given temporal object as a date.
+ * Used for interoperability in situations where old and new Java API are mixed.
+ *
+ * @param time the temporal object to return as a date, or {@code null}.
+ * @return the given temporal object as a date, or {@code null} if the given argument was null.
+ * @throws ArithmeticException if numeric overflow occurs.
+ */
+ public static Date toDate(final Instant time) {
+ return (time == null) ? null : new TemporalDate(time);
+ }
+
+ /**
+ * Returns the given date as a temporal object.
+ * Used for interoperability in situations where old and new Java API are mixed.
+ *
+ * @param time the date to return as a temporal object, or {@code null}.
+ * @return the given date as a temporal object, or {@code null} if the given argument was null.
+ */
+ public static Temporal toTemporal(final Date time) {
+ return (time == null) ? null : (time instanceof TemporalDate) ? ((TemporalDate) time).temporal : time.toInstant();
+ }
+
+ /**
+ * Returns the given date as an instant object.
+ * Used for interoperability in situations where old and new Java API are mixed.
+ *
+ * @param time the date to return as an instant object, or {@code null}.
+ * @return the given date as an instant object, or {@code null} if the given argument was null.
+ */
+ public static Instant toInstant(final Date time) {
+ return (time == null) ? null : time.toInstant();
+ }
+
+ /**
+ * Converts the given temporal object into an instant.
+ * If the timezone is unspecified, then UTC is assumed.
+ *
+ * @param date the temporal object to convert, or {@code null}.
+ * @param zone the timezone to use if the time is local, or {@code null} if none.
+ * @return the instant for the given temporal object, or {@code null} if the argument was null.
+ * @throws DateTimeException if the given date does not support a field required by this method.
+ */
+ public static Instant toInstant(final TemporalAccessor date, final ZoneId zone) {
+ if (date == null) {
+ return null;
+ }
+ if (date instanceof Instant) {
+ return (Instant) date;
+ } else if (date instanceof OffsetDateTime) {
+ return ((OffsetDateTime) date).toInstant();
+ } else if (date instanceof ChronoZonedDateTime) {
+ return ((ChronoZonedDateTime) date).toInstant();
+ } else if (zone != null) {
+ if (date instanceof LocalDateTime) {
+ final var t = (LocalDateTime) date;
+ if (zone instanceof ZoneOffset) {
+ return t.atOffset((ZoneOffset) zone).toInstant();
+ } else {
+ return t.atZone(zone).toInstant();
+ }
+ } else if (date instanceof LocalDate) {
+ final var t = (LocalDate) date;
+ return t.atStartOfDay(zone).toInstant();
+ }
+ }
+ Instant time;
+ final ChronoField nano;
+ if (zone == null || date.isSupported(ChronoField.INSTANT_SECONDS)) {
+ time = Instant.ofEpochSecond(date.getLong(ChronoField.INSTANT_SECONDS));
+ nano = ChronoField.NANO_OF_SECOND;
+ } else if (zone.equals(ZoneOffset.UTC)) {
+ // Note that the timezone of the temporal value is unknown here. We assume UTC.
+ time = Instant.ofEpochSecond(Math.multiplyExact(date.getLong(ChronoField.EPOCH_DAY), Constants.SECONDS_PER_DAY));
+ nano = ChronoField.NANO_OF_DAY;
+ } else {
+ throw new DateTimeException(Errors.format(Errors.Keys.CanNotConvertFromType_2, date.getClass(), Instant.class));
+ }
+ if (date.isSupported(nano)) {
+ time = time.plusNanos(date.getLong(nano));
+ }
+ return time;
+ }
+
+ /**
+ * Returns this date as an instant.
+ */
+ @Override
+ public Instant toInstant() {
+ if (temporal instanceof Instant) {
+ return (Instant) temporal;
+ }
+ return super.toInstant();
+ }
+
+ /**
+ * Adds the given amount of seconds to the given instant.
+ *
+ * @param time the instant to which to add seconds, or {@code null}.
+ * @param value number of seconds.
+ * @return the shifted time, or {@code null} if the given instant was null or the given value was NaN.
+ */
+ public static Instant addSeconds(final Instant time, final double value) {
+ if (time == null || Double.isNaN(value)) {
+ return null;
+ }
+ final long r = Math.round(value);
+ return time.plusSeconds(r).plusNanos(Math.round((value - r) * Constants.NANOS_PER_SECOND));
+ }
+
+ /**
+ * Returns {@code true} if objects of the given class have day, month and hour fields.
+ * This method is defined here for having a single class where to concentrate such heuristic rules.
+ * Note that {@link Instant} does not have date fields.
+ *
+ * @param date class of object to test (may be {@code null}).
+ * @return whether the given class is {@link LocalDate} or one of the classes with date + time.
+ * This list may be expanded in future versions.
+ */
+ public static boolean hasDateFields(final Class<?> date) {
+ return date == LocalDate.class
+ || date == LocalDateTime.class
+ || date == OffsetDateTime.class
+ || date == ZonedDateTime.class;
+ }
+
+ /**
+ * Returns {@code true} if objects of the given class have time fields.
+ * This method is defined here for having a single class where to concentrate such heuristic rules.
+ * Note that {@link Instant} does not have hour fields.
+ *
+ * @param date class of object to test (may be {@code null}).
+ * @return whether the given class is {@link LocalTime}, {@link OffsetTime} or one of the classes with date + time.
+ * This list may be expanded in future versions.
+ */
+ public static boolean hasTimeFields(final Class<?> date) {
+ return date == LocalTime.class
+ || date == OffsetTime.class
+ || date == LocalDateTime.class
+ || date == OffsetDateTime.class
+ || date == ZonedDateTime.class;
+ }
+}
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java
index 74998ec..77f1059 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java
@@ -60,1032 +60,1032 @@
/**
* ‘{0}’ is already initialized.
*/
- public static final short AlreadyInitialized_1 = 188;
+ public static final short AlreadyInitialized_1 = 1;
/**
* Name “{2}” is ambiguous because it can be understood as either “{0}” or “{1}”.
*/
- public static final short AmbiguousName_3 = 1;
+ public static final short AmbiguousName_3 = 2;
/**
* Computation in background failed.
*/
- public static final short BackgroundComputationFailed = 191;
+ public static final short BackgroundComputationFailed = 3;
/**
* This object can iterate only once.
*/
- public static final short CanIterateOnlyOnce = 172;
+ public static final short CanIterateOnlyOnce = 4;
/**
* No element can be added to this set because properties ‘{0}’ and ‘{1}’ are mutually
* exclusive.
*/
- public static final short CanNotAddToExclusiveSet_2 = 2;
+ public static final short CanNotAddToExclusiveSet_2 = 5;
/**
* Cannot assign units “{1}” to dimension “{0}”.
*/
- public static final short CanNotAssignUnitToDimension_2 = 3;
+ public static final short CanNotAssignUnitToDimension_2 = 6;
/**
* Cannot assign units “{1}” to variable “{0}”.
*/
- public static final short CanNotAssignUnitToVariable_2 = 183;
+ public static final short CanNotAssignUnitToVariable_2 = 7;
/**
* Cannot assign “{1}” to “{0}”.
*/
- public static final short CanNotAssign_2 = 4;
+ public static final short CanNotAssign_2 = 8;
/**
* Cannot compute “{0}”.
*/
- public static final short CanNotCompute_1 = 5;
+ public static final short CanNotCompute_1 = 9;
/**
* Cannot connect to “{0}”.
*/
- public static final short CanNotConnectTo_1 = 6;
+ public static final short CanNotConnectTo_1 = 10;
/**
* Cannot convert from type ‘{0}’ to type ‘{1}’.
*/
- public static final short CanNotConvertFromType_2 = 7;
+ public static final short CanNotConvertFromType_2 = 11;
/**
* Cannot convert value “{0}” to type ‘{1}’.
*/
- public static final short CanNotConvertValue_2 = 8;
+ public static final short CanNotConvertValue_2 = 12;
/**
* Cannot copy “{0}”.
*/
- public static final short CanNotCopy_1 = 169;
+ public static final short CanNotCopy_1 = 13;
/**
* Cannot open “{0}”.
*/
- public static final short CanNotOpen_1 = 9;
+ public static final short CanNotOpen_1 = 14;
/**
* Cannot parse “{0}”.
*/
- public static final short CanNotParse_1 = 180;
+ public static final short CanNotParse_1 = 15;
/**
* Cannot process property “{1}” located at path “{0}”. The reason is: {2}
*/
- public static final short CanNotProcessPropertyAtPath_3 = 184;
+ public static final short CanNotProcessPropertyAtPath_3 = 16;
/**
* Cannot process property “{0}”. The reason is: {1}
*/
- public static final short CanNotProcessProperty_2 = 152;
+ public static final short CanNotProcessProperty_2 = 17;
/**
* Cannot read property “{1}” in file “{0}”.
*/
- public static final short CanNotReadPropertyInFile_2 = 11;
+ public static final short CanNotReadPropertyInFile_2 = 18;
/**
* Cannot read “{0}”.
*/
- public static final short CanNotRead_1 = 12;
+ public static final short CanNotRead_1 = 19;
/**
* Cannot read “{0}” at line {1}, column {2}.
*/
- public static final short CanNotRead_3 = 34;
+ public static final short CanNotRead_3 = 20;
/**
* Cannot represent “{1}” in a strictly standard-compliant {0} format.
*/
- public static final short CanNotRepresentInFormat_2 = 13;
+ public static final short CanNotRepresentInFormat_2 = 21;
/**
* Cannot resolve “{0}” as an absolute path.
*/
- public static final short CanNotResolveAsAbsolutePath_1 = 106;
+ public static final short CanNotResolveAsAbsolutePath_1 = 22;
/**
* Cannot set a value for parameter “{0}”.
*/
- public static final short CanNotSetParameterValue_1 = 14;
+ public static final short CanNotSetParameterValue_1 = 23;
/**
* Cannot set a value for property “{0}”.
*/
- public static final short CanNotSetPropertyValue_1 = 15;
+ public static final short CanNotSetPropertyValue_1 = 24;
/**
* Cannot store the {0} value in this vector.
*/
- public static final short CanNotStoreInVector_1 = 175;
+ public static final short CanNotStoreInVector_1 = 25;
/**
* Cannot transform envelope.
*/
- public static final short CanNotTransformEnvelope = 16;
+ public static final short CanNotTransformEnvelope = 26;
/**
* Cannot write “{1}” as a file in the {0} format.
*/
- public static final short CanNotWriteFile_2 = 17;
+ public static final short CanNotWriteFile_2 = 27;
/**
* Circular reference.
*/
- public static final short CircularReference = 18;
+ public static final short CircularReference = 28;
/**
* Class ‘{0}’ is not final.
*/
- public static final short ClassNotFinal_1 = 19;
+ public static final short ClassNotFinal_1 = 29;
/**
* Cannot clone an object of type ‘{0}’.
*/
- public static final short CloneNotSupported_1 = 20;
+ public static final short CloneNotSupported_1 = 30;
/**
* Connection is closed.
*/
- public static final short ConnectionClosed = 194;
+ public static final short ConnectionClosed = 31;
/**
* Cross references are not supported.
*/
- public static final short CrossReferencesNotSupported = 167;
+ public static final short CrossReferencesNotSupported = 32;
/**
* Database error while creating a ‘{0}’ object for the “{1}” identifier.
*/
- public static final short DatabaseError_2 = 21;
+ public static final short DatabaseError_2 = 33;
/**
* Failed to {0,choice,0#insert|1#update} record “{2}” in database table “{1}”.
*/
- public static final short DatabaseUpdateFailure_3 = 174;
+ public static final short DatabaseUpdateFailure_3 = 34;
/**
* Thread “{0}” is dead.
*/
- public static final short DeadThread_1 = 22;
+ public static final short DeadThread_1 = 35;
/**
* This instance of ‘{0}’ has been disposed.
*/
- public static final short DisposedInstanceOf_1 = 23;
+ public static final short DisposedInstanceOf_1 = 36;
/**
* Element “{0}” is duplicated.
*/
- public static final short DuplicatedElement_1 = 24;
+ public static final short DuplicatedElement_1 = 37;
/**
* File “{0}” is referenced more than once.
*/
- public static final short DuplicatedFileReference_1 = 186;
+ public static final short DuplicatedFileReference_1 = 38;
/**
* Name or identifier “{0}” is used more than once.
*/
- public static final short DuplicatedIdentifier_1 = 25;
+ public static final short DuplicatedIdentifier_1 = 39;
/**
* Value {0,number} is used more than once.
*/
- public static final short DuplicatedNumber_1 = 187;
+ public static final short DuplicatedNumber_1 = 40;
/**
* Option “{0}” is duplicated.
*/
- public static final short DuplicatedOption_1 = 26;
+ public static final short DuplicatedOption_1 = 41;
/**
* Element “{0}” is already present.
*/
- public static final short ElementAlreadyPresent_1 = 27;
+ public static final short ElementAlreadyPresent_1 = 42;
/**
* Element “{0}” has not been found.
*/
- public static final short ElementNotFound_1 = 28;
+ public static final short ElementNotFound_1 = 43;
/**
* Argument ‘{0}’ shall not be empty.
*/
- public static final short EmptyArgument_1 = 29;
+ public static final short EmptyArgument_1 = 44;
/**
* The dictionary shall contain at least one entry.
*/
- public static final short EmptyDictionary = 30;
+ public static final short EmptyDictionary = 45;
/**
* Envelope must be at least two-dimensional and non-empty.
*/
- public static final short EmptyEnvelope2D = 31;
+ public static final short EmptyEnvelope2D = 46;
/**
* Property named “{0}” shall not be empty.
*/
- public static final short EmptyProperty_1 = 32;
+ public static final short EmptyProperty_1 = 47;
/**
* An error occurred in file “{0}” at line {1}.
*/
- public static final short ErrorInFileAtLine_2 = 33;
+ public static final short ErrorInFileAtLine_2 = 48;
/**
* A size of {1} elements is excessive for the “{0}” list.
*/
- public static final short ExcessiveListSize_2 = 36;
+ public static final short ExcessiveListSize_2 = 49;
/**
* For this algorithm, {0} is an excessive number of dimensions.
*/
- public static final short ExcessiveNumberOfDimensions_1 = 37;
+ public static final short ExcessiveNumberOfDimensions_1 = 50;
/**
* No factory of kind ‘{0}’ found.
*/
- public static final short FactoryNotFound_1 = 38;
+ public static final short FactoryNotFound_1 = 51;
/**
* File “{0}” has not been found.
*/
- public static final short FileNotFound_1 = 39;
+ public static final short FileNotFound_1 = 52;
/**
* Attribute “{0}” is not allowed for an object of type ‘{1}’.
*/
- public static final short ForbiddenAttribute_2 = 40;
+ public static final short ForbiddenAttribute_2 = 53;
/**
* Property “{0}” is not allowed.
*/
- public static final short ForbiddenProperty_1 = 41;
+ public static final short ForbiddenProperty_1 = 54;
/**
* “{0}” uses two or more different units of measurement.
*/
- public static final short HeterogynousUnitsIn_1 = 202;
+ public static final short HeterogynousUnitsIn_1 = 55;
/**
* Identifier “{1}” is not in “{0}” namespace.
*/
- public static final short IdentifierNotInNamespace_2 = 199;
+ public static final short IdentifierNotInNamespace_2 = 56;
/**
* Argument ‘{0}’ cannot be an instance of ‘{1}’.
*/
- public static final short IllegalArgumentClass_2 = 42;
+ public static final short IllegalArgumentClass_2 = 57;
/**
* Argument ‘{0}’ cannot be an instance of ‘{2}’. Expected an instance of ‘{1}’ or derived
* type.
*/
- public static final short IllegalArgumentClass_3 = 43;
+ public static final short IllegalArgumentClass_3 = 58;
/**
* Argument ‘{0}’ cannot take the “{1}” value.
*/
- public static final short IllegalArgumentValue_2 = 45;
+ public static final short IllegalArgumentValue_2 = 59;
/**
* Illegal bits pattern: {0}.
*/
- public static final short IllegalBitsPattern_1 = 46;
+ public static final short IllegalBitsPattern_1 = 60;
/**
* Coordinate reference system cannot be of type ‘{0}’.
*/
- public static final short IllegalCRSType_1 = 47;
+ public static final short IllegalCRSType_1 = 61;
/**
* The “{2}” character in “{1}” is not permitted by the “{0}” format.
*/
- public static final short IllegalCharacterForFormat_3 = 48;
+ public static final short IllegalCharacterForFormat_3 = 62;
/**
* The “{1}” character cannot be used for “{0}”.
*/
- public static final short IllegalCharacter_2 = 49;
+ public static final short IllegalCharacter_2 = 63;
/**
* Class ‘{1}’ is illegal. It must be ‘{0}’ or a derived class.
*/
- public static final short IllegalClass_2 = 50;
+ public static final short IllegalClass_2 = 64;
/**
* The [{0} … {1}] range of coordinate values is not valid for the “{2}” axis.
*/
- public static final short IllegalCoordinateRange_3 = 57;
+ public static final short IllegalCoordinateRange_3 = 65;
/**
* Coordinate system cannot be “{0}”.
*/
- public static final short IllegalCoordinateSystem_1 = 51;
+ public static final short IllegalCoordinateSystem_1 = 66;
/**
* The “{1}” pattern cannot be applied to formatting of objects of type ‘{0}’.
*/
- public static final short IllegalFormatPatternForClass_2 = 52;
+ public static final short IllegalFormatPatternForClass_2 = 67;
/**
* “{1}” is not a valid identifier for the “{0}” code space.
*/
- public static final short IllegalIdentifierForCodespace_2 = 53;
+ public static final short IllegalIdentifierForCodespace_2 = 68;
/**
* The “{0}” language is not recognized.
*/
- public static final short IllegalLanguageCode_1 = 54;
+ public static final short IllegalLanguageCode_1 = 69;
/**
* Illegal mapping: {0} → {1}.
*/
- public static final short IllegalMapping_2 = 185;
+ public static final short IllegalMapping_2 = 70;
/**
* Member “{0}” cannot be associated to type “{1}”.
*/
- public static final short IllegalMemberType_2 = 55;
+ public static final short IllegalMemberType_2 = 71;
/**
* Option ‘{0}’ cannot take the “{1}” value.
*/
- public static final short IllegalOptionValue_2 = 56;
+ public static final short IllegalOptionValue_2 = 72;
/**
* Property “{0}” does not accept instances of ‘{1}’.
*/
- public static final short IllegalPropertyValueClass_2 = 58;
+ public static final short IllegalPropertyValueClass_2 = 73;
/**
* Expected an instance of ‘{1}’ for the “{0}” property, but got an instance of ‘{2}’.
*/
- public static final short IllegalPropertyValueClass_3 = 59;
+ public static final short IllegalPropertyValueClass_3 = 74;
/**
* Property “{0}” cannot take the “{1}” value.
*/
- public static final short IllegalPropertyValue_2 = 198;
+ public static final short IllegalPropertyValue_2 = 75;
/**
* Range [{0} … {1}] is not valid.
*/
- public static final short IllegalRange_2 = 60;
+ public static final short IllegalRange_2 = 76;
/**
* Sexagesimal angle {0,number} is illegal because the {1,choice,0#minutes|1#seconds} field
* cannot take the {2,number} value.
*/
- public static final short IllegalSexagesimalField_3 = 44;
+ public static final short IllegalSexagesimalField_3 = 77;
/**
* Value {1} for “{0}” is not a valid Unicode code point.
*/
- public static final short IllegalUnicodeCodePoint_2 = 61;
+ public static final short IllegalUnicodeCodePoint_2 = 78;
/**
* Illegal value for property “{1}” in “{0}”.
*/
- public static final short IllegalValueForProperty_2 = 196;
+ public static final short IllegalValueForProperty_2 = 79;
/**
* Cannot use the {1} format with “{0}”.
*/
- public static final short IncompatibleFormat_2 = 62;
+ public static final short IncompatibleFormat_2 = 80;
/**
* Property “{0}” has an incompatible value.
*/
- public static final short IncompatiblePropertyValue_1 = 63;
+ public static final short IncompatiblePropertyValue_1 = 81;
/**
* The “{0}” unit of measurement has dimension of ‘{1}’ ({2}). It is incompatible with
* dimension of ‘{3}’ ({4}).
*/
- public static final short IncompatibleUnitDimension_5 = 64;
+ public static final short IncompatibleUnitDimension_5 = 82;
/**
* Unit “{0}” is incompatible with current value.
*/
- public static final short IncompatibleUnit_1 = 65;
+ public static final short IncompatibleUnit_1 = 83;
/**
* Units “{0}” and “{1}” are incompatible.
*/
- public static final short IncompatibleUnits_2 = 66;
+ public static final short IncompatibleUnits_2 = 84;
/**
* Value “{1}” of attribute ‘{0}’ is inconsistent with other attributes.
*/
- public static final short InconsistentAttribute_2 = 67;
+ public static final short InconsistentAttribute_2 = 85;
/**
* Inconsistent table columns.
*/
- public static final short InconsistentTableColumns = 69;
+ public static final short InconsistentTableColumns = 86;
/**
* Unit of measurement “{0}” is inconsistent with coordinate system axes.
*/
- public static final short InconsistentUnitsForCS_1 = 70;
+ public static final short InconsistentUnitsForCS_1 = 87;
/**
* Index {0} is out of bounds.
*/
- public static final short IndexOutOfBounds_1 = 71;
+ public static final short IndexOutOfBounds_1 = 88;
/**
* Indices ({0}, {1}) are out of bounds.
*/
- public static final short IndicesOutOfBounds_2 = 72;
+ public static final short IndicesOutOfBounds_2 = 89;
/**
* Argument ‘{0}’ cannot take an infinite value.
*/
- public static final short InfiniteArgumentValue_1 = 73;
+ public static final short InfiniteArgumentValue_1 = 90;
/**
* Integer overflow during {0} bits arithmetic operation.
*/
- public static final short IntegerOverflow_1 = 10;
+ public static final short IntegerOverflow_1 = 91;
/**
* Interrupted while waiting result.
*/
- public static final short InterruptedWhileWaitingResult = 192;
+ public static final short InterruptedWhileWaitingResult = 92;
/**
* “{0}” is an invalid version identifier.
*/
- public static final short InvalidVersionIdentifier_1 = 179;
+ public static final short InvalidVersionIdentifier_1 = 93;
/**
* Key “{0}” is associated twice to different values.
*/
- public static final short KeyCollision_1 = 75;
+ public static final short KeyCollision_1 = 94;
/**
* Attribute “{0}” is mandatory for an object of type ‘{1}’.
*/
- public static final short MandatoryAttribute_2 = 76;
+ public static final short MandatoryAttribute_2 = 95;
/**
* Mismatched array lengths.
*/
- public static final short MismatchedArrayLengths = 77;
+ public static final short MismatchedArrayLengths = 96;
/**
* Mismatched axes “{1}” and “{2}” at dimension {0}.
*/
- public static final short MismatchedAxes_3 = 200;
+ public static final short MismatchedAxes_3 = 97;
/**
* The coordinate reference system must be the same for all objects.
*/
- public static final short MismatchedCRS = 78;
+ public static final short MismatchedCRS = 98;
/**
* The “{0}” coordinate reference system has {1} dimension{1,choice,1#|2#s}, but the given
* geometry is {2}-dimensional.
*/
- public static final short MismatchedDimensionForCRS_3 = 79;
+ public static final short MismatchedDimensionForCRS_3 = 99;
/**
* Mismatched object dimensions: {0}D and {1}D.
*/
- public static final short MismatchedDimension_2 = 80;
+ public static final short MismatchedDimension_2 = 100;
/**
* Argument ‘{0}’ has {2} dimension{2,choice,1#|2#s}, while {1} was expected.
*/
- public static final short MismatchedDimension_3 = 81;
+ public static final short MismatchedDimension_3 = 101;
/**
* The grid geometry must be the same for “{0}” and “{1}”.
*/
- public static final short MismatchedGridGeometry_2 = 82;
+ public static final short MismatchedGridGeometry_2 = 102;
/**
* Mismatched matrix sizes: expected {0}×{1} but got {2}×{3}.
*/
- public static final short MismatchedMatrixSize_4 = 83;
+ public static final short MismatchedMatrixSize_4 = 103;
/**
* The “{0}” transform has {3} {1,choice,0#source|1#target} dimension{3,choice,1#|2#s}, while
* {2} was expected.
*/
- public static final short MismatchedTransformDimension_4 = 190;
+ public static final short MismatchedTransformDimension_4 = 104;
/**
* Missing a ‘{1}’ character in “{0}” element.
*/
- public static final short MissingCharacterInElement_2 = 84;
+ public static final short MissingCharacterInElement_2 = 105;
/**
* Missing a “{1}” component in “{0}”.
*/
- public static final short MissingComponentInElement_2 = 85;
+ public static final short MissingComponentInElement_2 = 106;
/**
* JAXB context has not been specified.
*/
- public static final short MissingJAXBContext = 86;
+ public static final short MissingJAXBContext = 107;
/**
* Missing or empty ‘{1}’ attribute in “{0}”.
*/
- public static final short MissingOrEmptyAttribute_2 = 182;
+ public static final short MissingOrEmptyAttribute_2 = 108;
/**
* This operation requires the “{0}” module.
*/
- public static final short MissingRequiredModule_1 = 87;
+ public static final short MissingRequiredModule_1 = 109;
/**
* Missing value for “{0}” option.
*/
- public static final short MissingValueForOption_1 = 88;
+ public static final short MissingValueForOption_1 = 110;
/**
* Missing value for “{0}” property.
*/
- public static final short MissingValueForProperty_1 = 89;
+ public static final short MissingValueForProperty_1 = 111;
/**
* Missing value for “{1}” property in “{0}”.
*/
- public static final short MissingValueForProperty_2 = 197;
+ public static final short MissingValueForProperty_2 = 112;
/**
* Missing value in the “{0}” column.
*/
- public static final short MissingValueInColumn_1 = 90;
+ public static final short MissingValueInColumn_1 = 113;
/**
* Cannot return a single value for “{0}” because there is at least two occurrences, at indices
* {1} and {2}.
*/
- public static final short MultiOccurenceValueAtIndices_3 = 173;
+ public static final short MultiOccurenceValueAtIndices_3 = 114;
/**
* Options “{0}” and “{1}” are mutually exclusive.
*/
- public static final short MutuallyExclusiveOptions_2 = 91;
+ public static final short MutuallyExclusiveOptions_2 = 115;
/**
* Native interfaces “{1}” not available for the {0} platform.
*/
- public static final short NativeInterfacesNotFound_2 = 176;
+ public static final short NativeInterfacesNotFound_2 = 116;
/**
* Argument ‘{0}’ shall not be negative. The given value was {1}.
*/
- public static final short NegativeArgument_2 = 92;
+ public static final short NegativeArgument_2 = 117;
/**
* Cannot create a “{0}” array of negative length.
*/
- public static final short NegativeArrayLength_1 = 93;
+ public static final short NegativeArrayLength_1 = 118;
/**
* Nested “{0}” elements are not allowed.
*/
- public static final short NestedElementNotAllowed_1 = 94;
+ public static final short NestedElementNotAllowed_1 = 119;
/**
* The object is nil for the following reason: {0}.
*/
- public static final short NilObject_1 = 204;
+ public static final short NilObject_1 = 120;
/**
* No value is associated to “{0}”.
*/
- public static final short NoSuchValue_1 = 95;
+ public static final short NoSuchValue_1 = 121;
/**
* Node “{0}” cannot be a child of itself.
*/
- public static final short NodeChildOfItself_1 = 96;
+ public static final short NodeChildOfItself_1 = 122;
/**
* Node “{0}” already has another parent.
*/
- public static final short NodeHasAnotherParent_1 = 97;
+ public static final short NodeHasAnotherParent_1 = 123;
/**
* Node “{0}” has no parent.
*/
- public static final short NodeHasNoParent_1 = 98;
+ public static final short NodeHasNoParent_1 = 124;
/**
* Node “{0}” is a leaf.
*/
- public static final short NodeIsLeaf_1 = 99;
+ public static final short NodeIsLeaf_1 = 125;
/**
* “{0}” is not an angular unit.
*/
- public static final short NonAngularUnit_1 = 100;
+ public static final short NonAngularUnit_1 = 126;
/**
* Missing a ‘{1}’ parenthesis in “{0}”.
*/
- public static final short NonEquilibratedParenthesis_2 = 101;
+ public static final short NonEquilibratedParenthesis_2 = 127;
/**
* No horizontal component found in the “{0}” coordinate reference system.
*/
- public static final short NonHorizontalCRS_1 = 201;
+ public static final short NonHorizontalCRS_1 = 128;
/**
* Conversion is not invertible.
*/
- public static final short NonInvertibleConversion = 102;
+ public static final short NonInvertibleConversion = 129;
/**
* “{0}” is not a linear unit.
*/
- public static final short NonLinearUnit_1 = 103;
+ public static final short NonLinearUnit_1 = 130;
/**
* The scale of measurement for “{0}” unit is not a ratio scale.
*/
- public static final short NonRatioUnit_1 = 104;
+ public static final short NonRatioUnit_1 = 131;
/**
* “{0}” is not a scale unit.
*/
- public static final short NonScaleUnit_1 = 105;
+ public static final short NonScaleUnit_1 = 132;
/**
* “{0}” is not a time unit.
*/
- public static final short NonTemporalUnit_1 = 107;
+ public static final short NonTemporalUnit_1 = 133;
/**
* No element for the “{0}” identifier, or the identifier is a forward reference.
*/
- public static final short NotABackwardReference_1 = 108;
+ public static final short NotABackwardReference_1 = 134;
/**
* Value of ‘{0}’ shall be a {1,choice,0#divisor|1#multiple} of {2} but the given value is {3}.
*/
- public static final short NotADivisorOrMultiple_4 = 193;
+ public static final short NotADivisorOrMultiple_4 = 135;
/**
* “{0}” is not a key-value pair.
*/
- public static final short NotAKeyValuePair_1 = 109;
+ public static final short NotAKeyValuePair_1 = 136;
/**
* Argument ‘{0}’ shall not be NaN (Not-a-Number).
*/
- public static final short NotANumber_1 = 110;
+ public static final short NotANumber_1 = 137;
/**
* Class ‘{0}’ is not a primitive type wrapper.
*/
- public static final short NotAPrimitiveWrapper_1 = 111;
+ public static final short NotAPrimitiveWrapper_1 = 138;
/**
* Text “{0}” is not a Unicode identifier.
*/
- public static final short NotAUnicodeIdentifier_1 = 112;
+ public static final short NotAUnicodeIdentifier_1 = 139;
/**
* {0} is not an integer value.
*/
- public static final short NotAnInteger_1 = 171;
+ public static final short NotAnInteger_1 = 140;
/**
* Argument ‘{0}’ shall not be null.
*/
- public static final short NullArgument_1 = 113;
+ public static final short NullArgument_1 = 141;
/**
* ‘{0}’ collection does not accept null elements.
*/
- public static final short NullCollectionElement_1 = 114;
+ public static final short NullCollectionElement_1 = 142;
/**
* Null key is not allowed in this dictionary.
*/
- public static final short NullMapKey = 115;
+ public static final short NullMapKey = 143;
/**
* Null values are not allowed in this dictionary.
*/
- public static final short NullMapValue = 116;
+ public static final short NullMapValue = 144;
/**
* Unexpected null value in record “{2}” for the column “{1}” in table “{0}”.
*/
- public static final short NullValueInTable_3 = 117;
+ public static final short NullValueInTable_3 = 145;
/**
* Array length is {0}, while we expected an even length.
*/
- public static final short OddArrayLength_1 = 118;
+ public static final short OddArrayLength_1 = 146;
/**
* “{1}” is opened in {0,choice,0#read|1#write}-only mode.
*/
- public static final short OpenedReadOrWriteOnly_2 = 203;
+ public static final short OpenedReadOrWriteOnly_2 = 147;
/**
* Coordinate is outside the domain of validity.
*/
- public static final short OutsideDomainOfValidity = 119;
+ public static final short OutsideDomainOfValidity = 148;
/**
* No property named “{1}” has been found in “{0}”.
*/
- public static final short PropertyNotFound_2 = 120;
+ public static final short PropertyNotFound_2 = 149;
/**
* Record “{1}” is already defined in schema “{0}”.
*/
- public static final short RecordAlreadyDefined_2 = 121;
+ public static final short RecordAlreadyDefined_2 = 150;
/**
* No record found in “{0}” table for “{1}” key.
*/
- public static final short RecordNotFound_2 = 122;
+ public static final short RecordNotFound_2 = 151;
/**
* Recursive call while creating an object for the “{0}” key.
*/
- public static final short RecursiveCreateCallForKey_1 = 123;
+ public static final short RecursiveCreateCallForKey_1 = 152;
/**
* A decimal separator is required.
*/
- public static final short RequireDecimalSeparator = 124;
+ public static final short RequireDecimalSeparator = 153;
/**
* Thread “{0}” seems stalled.
*/
- public static final short StalledThread_1 = 125;
+ public static final short StalledThread_1 = 154;
/**
* Table “{0}” has not been found.
*/
- public static final short TableNotFound_1 = 126;
+ public static final short TableNotFound_1 = 155;
/**
* Expected at least {0,number} argument{0,choice,1#|2#s}, but got {1,number}.
*/
- public static final short TooFewArguments_2 = 127;
+ public static final short TooFewArguments_2 = 156;
/**
* Collection “{0}” contains only {2,number} element{2,choice,1#|2#s} while at least {1,number}
* elements were expected.
*/
- public static final short TooFewCollectionElements_3 = 74;
+ public static final short TooFewCollectionElements_3 = 157;
/**
* Too few occurrences of “{1}”. Expected at least {0,number} of them.
*/
- public static final short TooFewOccurrences_2 = 128;
+ public static final short TooFewOccurrences_2 = 158;
/**
* Expected at most {0,number} argument{0,choice,1#|2#s}, but got {1,number}.
*/
- public static final short TooManyArguments_2 = 129;
+ public static final short TooManyArguments_2 = 159;
/**
* Collection “{0}” contains {2,number} elements while at most {1,number} element{1,choice,1#
* was|2#s were} expected.
*/
- public static final short TooManyCollectionElements_3 = 35;
+ public static final short TooManyCollectionElements_3 = 160;
/**
* Too many occurrences of “{1}”. The maximum is {0,number}.
*/
- public static final short TooManyOccurrences_2 = 130;
+ public static final short TooManyOccurrences_2 = 161;
/**
* Tree depth exceeds the maximum.
*/
- public static final short TreeDepthExceedsMaximum = 131;
+ public static final short TreeDepthExceedsMaximum = 162;
/**
* Ordering between “{0}” and “{1}” elements is undefined.
*/
- public static final short UndefinedOrderingForElements_2 = 132;
+ public static final short UndefinedOrderingForElements_2 = 163;
/**
* Expected an array of length {0,number}, but got {1,number}.
*/
- public static final short UnexpectedArrayLength_2 = 133;
+ public static final short UnexpectedArrayLength_2 = 164;
/**
* Unexpected change in ‘{0}’.
*/
- public static final short UnexpectedChange_1 = 134;
+ public static final short UnexpectedChange_1 = 165;
/**
* The “{1}” characters after “{0}” were unexpected.
*/
- public static final short UnexpectedCharactersAfter_2 = 135;
+ public static final short UnexpectedCharactersAfter_2 = 166;
/**
* Text for ‘{0}’ was expected to {1,choice,0#begin|1#end} with “{2}”, but found “{3}”.
*/
- public static final short UnexpectedCharactersAtBound_4 = 136;
+ public static final short UnexpectedCharactersAtBound_4 = 167;
/**
* Unexpected end of file while reading “{0}”.
*/
- public static final short UnexpectedEndOfFile_1 = 137;
+ public static final short UnexpectedEndOfFile_1 = 168;
/**
* More characters were expected at the end of “{0}”.
*/
- public static final short UnexpectedEndOfString_1 = 138;
+ public static final short UnexpectedEndOfString_1 = 169;
/**
* File “{1}” seems to be encoded in another format than {0}.
*/
- public static final short UnexpectedFileFormat_2 = 139;
+ public static final short UnexpectedFileFormat_2 = 170;
/**
* The “{1}” name is not valid in this context, because the “{0}” namespace was expected.
*/
- public static final short UnexpectedNamespace_2 = 68;
+ public static final short UnexpectedNamespace_2 = 171;
/**
* Parameter “{0}” was not expected.
*/
- public static final short UnexpectedParameter_1 = 140;
+ public static final short UnexpectedParameter_1 = 172;
/**
* Property “{1}” was not expected in “{0}”.
*/
- public static final short UnexpectedProperty_2 = 141;
+ public static final short UnexpectedProperty_2 = 173;
/**
* Unexpected scale factor {1,number} for unit of measurement “{0}”.
*/
- public static final short UnexpectedScaleFactorForUnit_2 = 142;
+ public static final short UnexpectedScaleFactorForUnit_2 = 174;
/**
* Expected “{0}” to reference an instance of ‘{1}’, but found an instance of ‘{2}’.
*/
- public static final short UnexpectedTypeForReference_3 = 143;
+ public static final short UnexpectedTypeForReference_3 = 175;
/**
* Unexpected value “{1}” in “{0}” element.
*/
- public static final short UnexpectedValueInElement_2 = 144;
+ public static final short UnexpectedValueInElement_2 = 176;
/**
* ‘{0}’ has not been initialized.
*/
- public static final short Uninitialized_1 = 189;
+ public static final short Uninitialized_1 = 177;
/**
* Command “{0}” is not recognized.
*/
- public static final short UnknownCommand_1 = 145;
+ public static final short UnknownCommand_1 = 178;
/**
* “{1}” is not a known or supported value for the ‘{0}’ enumeration.
*/
- public static final short UnknownEnumValue_2 = 146;
+ public static final short UnknownEnumValue_2 = 179;
/**
* Keyword “{0}” is unknown.
*/
- public static final short UnknownKeyword_1 = 147;
+ public static final short UnknownKeyword_1 = 180;
/**
* Option “{0}” is not recognized.
*/
- public static final short UnknownOption_1 = 148;
+ public static final short UnknownOption_1 = 181;
/**
* Type ‘{0}’ is unknown in this context.
*/
- public static final short UnknownType_1 = 149;
+ public static final short UnknownType_1 = 182;
/**
* Unit “{0}” is not recognized.
*/
- public static final short UnknownUnit_1 = 150;
+ public static final short UnknownUnit_1 = 183;
/**
* The cell at column “{1}” of row “{0}” is unmodifiable.
*/
- public static final short UnmodifiableCellValue_2 = 151;
+ public static final short UnmodifiableCellValue_2 = 184;
/**
* This instance of ‘{0}’ is not modifiable.
*/
- public static final short UnmodifiableObject_1 = 153;
+ public static final short UnmodifiableObject_1 = 185;
/**
* Text “{1}” cannot be parsed as an object of type ‘{0}’.
*/
- public static final short UnparsableStringForClass_2 = 154;
+ public static final short UnparsableStringForClass_2 = 186;
/**
* Text “{1}” cannot be parsed as an object of type ‘{0}’, because of the “{2}” characters.
*/
- public static final short UnparsableStringForClass_3 = 155;
+ public static final short UnparsableStringForClass_3 = 187;
/**
* Cannot parse “{1}” in element “{0}”.
*/
- public static final short UnparsableStringInElement_2 = 156;
+ public static final short UnparsableStringInElement_2 = 188;
/**
* Coordinate reference system has not been specified.
*/
- public static final short UnspecifiedCRS = 157;
+ public static final short UnspecifiedCRS = 189;
/**
* No format is specified for objects of class ‘{0}’.
*/
- public static final short UnspecifiedFormatForClass_1 = 158;
+ public static final short UnspecifiedFormatForClass_1 = 190;
/**
* The “{0}” argument value is unsupported.
*/
- public static final short UnsupportedArgumentValue_1 = 170;
+ public static final short UnsupportedArgumentValue_1 = 191;
/**
* Axes with “{0}” direction are not supported by this operation.
*/
- public static final short UnsupportedAxisDirection_1 = 177;
+ public static final short UnsupportedAxisDirection_1 = 192;
/**
* The “{0}” coordinate system is not supported by this operation.
*/
- public static final short UnsupportedCoordinateSystem_1 = 178;
+ public static final short UnsupportedCoordinateSystem_1 = 193;
/**
* The “{0}” datum is not supported by this operation.
*/
- public static final short UnsupportedDatum_1 = 168;
+ public static final short UnsupportedDatum_1 = 194;
/**
* Version {1} of {0} format is not supported.
*/
- public static final short UnsupportedFormatVersion_2 = 159;
+ public static final short UnsupportedFormatVersion_2 = 195;
/**
* Format “{0}” is unsupported.
*/
- public static final short UnsupportedFormat_1 = 181;
+ public static final short UnsupportedFormat_1 = 196;
/**
* Cannot handle this instance of ‘{0}’ because arbitrary implementations are not yet
* supported.
*/
- public static final short UnsupportedImplementation_1 = 160;
+ public static final short UnsupportedImplementation_1 = 197;
/**
* The “{0}” interpolation is unsupported.
*/
- public static final short UnsupportedInterpolation_1 = 161;
+ public static final short UnsupportedInterpolation_1 = 198;
/**
* The ‘{0}’ operation is unsupported.
*/
- public static final short UnsupportedOperation_1 = 162;
+ public static final short UnsupportedOperation_1 = 199;
/**
* The ‘{0}’ type is not supported in this context.
*/
- public static final short UnsupportedType_1 = 163;
+ public static final short UnsupportedType_1 = 200;
/**
* XPath “{0}” is not recognized. The current implementation supports only simple paths.
*/
- public static final short UnsupportedXPath_1 = 195;
+ public static final short UnsupportedXPath_1 = 201;
/**
* A value is already defined for “{0}”.
*/
- public static final short ValueAlreadyDefined_1 = 164;
+ public static final short ValueAlreadyDefined_1 = 202;
/**
* Value ‘{0}’ = {1,number} is invalid. Expected a number greater than 0.
*/
- public static final short ValueNotGreaterThanZero_2 = 165;
+ public static final short ValueNotGreaterThanZero_2 = 203;
/**
* Value ‘{0}’ = {3} is invalid. Expected a value in the [{1} … {2}] range.
*/
- public static final short ValueOutOfRange_4 = 166;
+ public static final short ValueOutOfRange_4 = 204;
}
/**
diff --git a/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/RangeFormatTest.java b/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/RangeFormatTest.java
index eeae5b3..7e2772d 100644
--- a/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/RangeFormatTest.java
+++ b/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/RangeFormatTest.java
@@ -30,7 +30,7 @@
import static java.lang.StrictMath.*;
import static java.lang.Double.POSITIVE_INFINITY;
import static java.lang.Double.NEGATIVE_INFINITY;
-import static org.apache.sis.util.privy.StandardDateFormat.UTC;
+import static org.apache.sis.util.privy.Constants.UTC;
// Test dependencies
import org.junit.jupiter.api.Test;
diff --git a/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/UnitFormatTest.java b/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/UnitFormatTest.java
index acddb61..12b52b6 100644
--- a/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/UnitFormatTest.java
+++ b/endorsed/src/org.apache.sis.util/test/org/apache/sis/measure/UnitFormatTest.java
@@ -87,6 +87,7 @@
verify(declared, "ARC_MINUTE", "", "′", "arc-minute", Units.ARC_MINUTE);
verify(declared, "ARC_SECOND", "", "″", "arc-second", Units.ARC_SECOND);
verify(declared, "GRAD", "", "grad", "grad", Units.GRAD);
+ verify(declared, "NANOSECOND", "T", "ns", "nanosecond", Units.NANOSECOND);
verify(declared, "MILLISECOND", "T", "ms", "millisecond", Units.MILLISECOND);
verify(declared, "SECOND", "T", "s", "second", Units.SECOND);
verify(declared, "MINUTE", "T", "min", "minute", Units.MINUTE);
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 3221913..ba464b6 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
@@ -47,7 +47,7 @@
import org.apache.sis.util.collection.TableColumn;
import org.apache.sis.util.collection.TreeTableFormat;
import org.apache.sis.util.privy.X364;
-import static org.apache.sis.util.privy.StandardDateFormat.UTC;
+import static org.apache.sis.util.privy.Constants.UTC;
// Test dependencies
import static org.junit.jupiter.api.Assertions.*;
@@ -235,19 +235,6 @@
}
/**
- * Formats the given date using the {@code "yyyy-MM-dd HH:mm:ss"} pattern in UTC timezone.
- *
- * @param date the date to format.
- * @return the date as a {@link String}.
- */
- public static String format(final Date date) {
- ArgumentChecks.ensureNonNull("date", date);
- synchronized (dateFormat) {
- return dateFormat.format(date);
- }
- }
-
- /**
* 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.
*
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 fe06e32..9c92a1e 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
@@ -29,7 +29,7 @@
import org.apache.sis.math.Statistics;
import org.apache.sis.math.StatisticsFormat;
import org.apache.sis.util.CharSequences;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
// Test dependencies
import org.junit.jupiter.api.Tag;
@@ -290,7 +290,7 @@
for (int i=0; i<10; i++) {
final long t = System.nanoTime();
out.printf("Cache size: %4d (after %3d ms)%n", cache.size(),
- round((t - time) / (double) StandardDateFormat.NANOS_PER_MILLISECOND));
+ round((t - time) / (double) Constants.NANOS_PER_MILLISECOND));
time = t;
Thread.sleep(250);
if (i >= 2) {
diff --git a/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/collection/RangeSetTest.java b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/collection/RangeSetTest.java
index 2e216b8..685210c 100644
--- a/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/collection/RangeSetTest.java
+++ b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/collection/RangeSetTest.java
@@ -25,8 +25,8 @@
import java.util.SortedSet;
import org.apache.sis.measure.Range;
import org.apache.sis.measure.NumberRange;
-import static org.apache.sis.util.privy.StandardDateFormat.MILLISECONDS_PER_DAY;
-import static org.apache.sis.util.privy.StandardDateFormat.NANOS_PER_SECOND;
+import static org.apache.sis.util.privy.Constants.MILLISECONDS_PER_DAY;
+import static org.apache.sis.util.privy.Constants.NANOS_PER_SECOND;
// Test dependencies
import org.junit.jupiter.api.Test;
diff --git a/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/privy/ConstantsTest.java b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/privy/ConstantsTest.java
new file mode 100644
index 0000000..aab12ff
--- /dev/null
+++ b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/privy/ConstantsTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util.privy;
+
+import java.util.concurrent.TimeUnit;
+
+// Test dependencies
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+import org.apache.sis.test.TestCase;
+
+
+/**
+ * Tests the {@link ConstantsTest} class.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public final class ConstantsTest extends TestCase {
+ /**
+ * Creates a new test case.
+ */
+ public ConstantsTest() {
+ }
+
+ /**
+ * Verifies the constant values related to time duration.
+ */
+ @Test
+ public void verifyConstantValues() {
+ assertEquals(TimeUnit.DAYS.toSeconds(1), Constants.SECONDS_PER_DAY);
+ assertEquals(TimeUnit.DAYS.toMillis(1), Constants.MILLISECONDS_PER_DAY);
+ assertEquals(TimeUnit.DAYS.toNanos(1), Constants.NANOSECONDS_PER_DAY);
+ assertEquals(TimeUnit.MILLISECONDS.toNanos(1), Constants.NANOS_PER_MILLISECOND);
+ assertEquals(TimeUnit.SECONDS.toNanos(1), Constants.NANOS_PER_SECOND);
+ assertEquals(365.24219 * (24*60*60 * 1000), Constants.MILLIS_PER_TROPICAL_YEAR, 0.00001 * (24*60*60 * 1000));
+ }
+}
diff --git a/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/privy/StandardDateFormatTest.java b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/privy/StandardDateFormatTest.java
index dbe092e..d20a8c7 100644
--- a/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/privy/StandardDateFormatTest.java
+++ b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/privy/StandardDateFormatTest.java
@@ -20,7 +20,6 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
-import java.util.concurrent.TimeUnit;
import java.text.ParseException;
// Test dependencies
@@ -43,17 +42,6 @@
}
/**
- * Verifies the {@link StandardDateFormat#MILLISECONDS_PER_DAY}, {@link StandardDateFormat#NANOS_PER_MILLISECOND}
- * and {@link StandardDateFormat#NANOS_PER_SECOND} constant values.
- */
- @Test
- public void verifyConstantValues() {
- assertEquals(TimeUnit.DAYS.toMillis(1), StandardDateFormat.MILLISECONDS_PER_DAY);
- assertEquals(TimeUnit.MILLISECONDS.toNanos(1), StandardDateFormat.NANOS_PER_MILLISECOND);
- assertEquals(TimeUnit.SECONDS.toNanos(1), StandardDateFormat.NANOS_PER_SECOND);
- }
-
- /**
* Tests {@link StandardDateFormat#toISO(CharSequence, int, int)}.
*/
@Test
@@ -139,9 +127,9 @@
*/
@Test
public void testNegativeYear() throws ParseException {
- final Date julian = new Date(-210866760000000L); // Same epoch as CommonCRS.Temporal.JULIAN.
- final String expected = "-4713-11-24T12:00:00.000"; // Proleptic Gregorian calendar, astronomical year.
- final StandardDateFormat f = new StandardDateFormat();
+ final var julian = new Date(-210866760000000L); // Same epoch as CommonCRS.Temporal.JULIAN.
+ final var expected = "-4713-11-24T12:00:00.000"; // Proleptic Gregorian calendar, astronomical year.
+ final var f = new StandardDateFormat();
assertEquals(expected, f.format(julian));
assertEquals(julian, f.parse(expected));
}
diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/MapCanvas.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/MapCanvas.java
index 28491f1..fce63c7 100644
--- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/MapCanvas.java
+++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/MapCanvas.java
@@ -89,7 +89,7 @@
import org.apache.sis.portrayal.RenderException;
import org.apache.sis.portrayal.TransformChangeEvent;
import static org.apache.sis.gui.internal.LogHandler.LOGGER;
-import static org.apache.sis.util.privy.StandardDateFormat.NANOS_PER_MILLISECOND;
+import static org.apache.sis.util.privy.Constants.NANOS_PER_MILLISECOND;
// Specific to the main branch:
import org.opengis.geometry.MismatchedDimensionException;
diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/IdentificationInfo.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/IdentificationInfo.java
index e5617a1..7a32422 100644
--- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/IdentificationInfo.java
+++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/metadata/IdentificationInfo.java
@@ -21,6 +21,7 @@
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.StringJoiner;
+import java.time.Instant;
import javafx.concurrent.Task;
import javafx.geometry.HPos;
import javafx.scene.canvas.Canvas;
@@ -362,7 +363,7 @@
*/
text = null;
Identifier identifier = null;
- Range<Date> timeRange = null;
+ Range<Instant> timeRange = null;
Range<Double> heights = null;
for (final Extent extent : nonNull(dataInfo != null ? dataInfo.getExtents() : null)) {
if (extent != null) {
@@ -379,7 +380,7 @@
}
final MeasurementRange<Double> v = Extents.getVerticalRange(extent);
if (v != null) heights = (heights != null) ? heights.union(v) : v;
- final Range<Date> t = Extents.getTimeRange(extent);
+ final Range<Instant> t = Extents.getTimeRange(extent, null).orElse(null);
if (t != null) timeRange = (timeRange != null) ? timeRange.union(t) : t;
}
}
@@ -398,12 +399,12 @@
addLine(Vocabulary.Keys.Extent, text);
if (timeRange != null) {
label = Vocabulary.Keys.StartDate;
- Date t = timeRange.getMinValue();
+ Instant t = timeRange.getMinValue();
if (t == null) {
t = timeRange.getMaxValue();
label = Vocabulary.Keys.EndDate;
}
- addLine(label, owner.format(t));
+ addLine(label, owner.format(Date.from(t)));
}
if (heights != null) {
final Double min = heights.getMinValue();
diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/AuthorityCodes.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/AuthorityCodes.java
index b9e523c..45565a8 100644
--- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/AuthorityCodes.java
+++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/referencing/AuthorityCodes.java
@@ -41,7 +41,7 @@
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.collection.BackingStoreException;
-import org.apache.sis.util.privy.StandardDateFormat;
+import org.apache.sis.util.privy.Constants;
import org.apache.sis.util.privy.Strings;
import org.apache.sis.gui.internal.BackgroundThreads;
import static org.apache.sis.gui.internal.LogHandler.LOGGER;
@@ -67,7 +67,7 @@
* The delay value is a compromise between fast user experience and giving enough time for doing a few
* large data transfers instead of many small data transfers.
*/
- private static final long REFRESH_DELAY = StandardDateFormat.NANOS_PER_SECOND / 10;
+ private static final long REFRESH_DELAY = Constants.NANOS_PER_SECOND / 10;
/**
* The table view which use this list, or {@code null} if we don't need this information anymore.
@@ -447,7 +447,7 @@
* the `toDescribe` list to be populated with more requests, then process them.
*/
if (codes.isEmpty()) {
- Thread.sleep(REFRESH_DELAY / StandardDateFormat.NANOS_PER_MILLISECOND);
+ Thread.sleep(REFRESH_DELAY / Constants.NANOS_PER_MILLISECOND);
return new PartialResult(null, processNameRequests(factory));
}
} catch (BackingStoreException e) {