001/*
002 *    GeoAPI - Java interfaces for OGC/ISO standards
003 *    Copyright © 2006-2024 Open Geospatial Consortium, Inc.
004 *    http://www.geoapi.org
005 *
006 *    Licensed under the Apache License, Version 2.0 (the "License");
007 *    you may not use this file except in compliance with the License.
008 *    You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *    Unless required by applicable law or agreed to in writing, software
013 *    distributed under the License is distributed on an "AS IS" BASIS,
014 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 *    See the License for the specific language governing permissions and
016 *    limitations under the License.
017 */
018package org.opengis.temporal;
019
020import java.util.Optional;
021import java.time.DateTimeException;
022import java.time.temporal.Temporal;
023import java.time.temporal.TemporalAmount;
024import java.time.temporal.TemporalField;
025import org.opengis.geometry.DirectPosition;
026import org.opengis.referencing.crs.TemporalCRS;
027import org.opengis.referencing.cs.CoordinateDataType;
028import org.opengis.annotation.UML;
029
030import static org.opengis.annotation.Obligation.OPTIONAL;
031import static org.opengis.annotation.Obligation.MANDATORY;
032import static org.opengis.annotation.Specification.ISO_19108;
033
034
035/**
036 * A zero-dimensional temporal primitive that represents position in time, equivalent to a point in space.
037 * In practice, an instant is an interval whose duration is less than the resolution of the time scale.
038 *
039 * @author  ISO 19108 (for abstract model and documentation)
040 * @author  Stephane Fellah (Image Matters)
041 * @author  Alexander Petkov
042 * @author  Martin Desruisseaux (Geomatys)
043 * @author  Remi Marechal (Geomatys).
044 * @since   3.1
045 * @version 3.1
046 */
047@UML(identifier="TM_Instant", specification=ISO_19108)
048public interface Instant extends TemporalPrimitive {
049    /**
050     * Returns the date, time or position on the time-scale represented by this primitive.
051     * The position can be of the following types:
052     *
053     * <ul>
054     *   <li><b>Date:</b> mapped to the {@link java.time.LocalDate} class.</li>
055     *   <li><b>Time:</b> mapped to the {@link java.time.LocalTime} or {@link java.time.OffsetTime} classes.</li>
056     *   <li><b>Date &amp; time:</b> mapped to the {@link java.time.LocalDateTime}, {@link java.time.OffsetDateTime}
057     *       or {@link java.time.ZonedDateTime} classes.</li>
058     *   <li><b>Temporal position:</b> mapped to a vendor-specific implementation of the {@link Temporal} interface,
059     *       possibly using custom {@linkplain TemporalField temporal fields}.
060     *       The returned object should also implement the {@link DirectPosition} interface for providing
061     *       the coordinate value together with its coordinate reference system (<abbr>CRS</abbr>).</li>
062     * </ul>
063     *
064     * The returned value should not be null,
065     * except if {@link #getIndeterminatePosition()} returns {@link IndeterminateValue#UNKNOWN}.
066     * In the case of {@link IndeterminateValue#NOW}, this method should return the current time.
067     *
068     * @departure harmonization
069     *   ISO 19108 defines this property as an union of {@code date8601}, {@code time8601}, {@code dateTime8601} or
070     *   {@code anyOther} properties. Unions are not explicitly supported by the Java language, but the same result
071     *   is achieved with type hierarchy. The mappings of ISO 19103 {@code Date}, {@code Time} and {@code DateTime}
072     *   types are described in above Javadoc. The {@code TM_TemporalPosition} type used by the {@code anyOther}
073     *   property is replaced by a vendor-specific {@link Temporal} implementation.
074     *
075     * @return the date, time or instant represented by this primitive.
076     *         Should not be null, except if {@linkplain IndeterminateValue#UNKNOWN unknown}.
077     */
078    @UML(identifier="position", obligation=MANDATORY, specification=ISO_19108)
079    Temporal getPosition();
080
081    /**
082     * Returns the reason why the temporal position is missing or inaccurate.
083     * When the temporal position is defined, this code provides a qualifier
084     * (e.g. "before" or "after") to the temporal position value.
085     *
086     * @departure integration
087     *   Moved from {@code TM_TemporalPosition} to {@code TM_Instant} because the former is replaced by
088     *   the {@link Temporal} standard Java interface, and {@code Temporal} does not have an association
089     *   to the {@code IndeterminateValue} code list.
090     *
091     * @return the reason why the position is indeterminate.
092     */
093    @UML(identifier="TM_TemporalPosition.indeterminatePosition", obligation=OPTIONAL, specification=ISO_19108)
094    default Optional<IndeterminateValue> getIndeterminatePosition() {
095        return Optional.empty();
096    }
097
098    /**
099     * Returns the distance from this instant to another instant or a period (optional operation).
100     * This is the absolute value of the difference between the temporal positions.
101     * If {@code other} is a period and this instant is contained within that period,
102     * then this method shall return a distance of zero.
103     *
104     * <h4>Exceptions</h4>
105     * This method shall throw an {@link IndeterminatePositionException}
106     * if at least one temporal position is {@linkplain #getIndeterminatePosition() indeterminate}.
107     * A {@link DateTimeException} may also be thrown
108     * if the temporal positions are associated to different {@link TemporalCRS},
109     * or if the coordinates are {@linkplain CoordinateDataType#INTEGER ordinal values},
110     * or if the {@link Temporal} objects do not support required {@linkplain TemporalField temporal fields}.
111     *
112     * @param  other the other object from which to measure the distance.
113     * @return the distance from this instant to another instant or period.
114     * @throws UnsupportedOperationException if this operation is not supported.
115     * @throws IndeterminatePositionException if at least one temporal position is indeterminate.
116     * @throws DateTimeException if the duration cannot be computed between the two temporal primitives.
117     * @throws ArithmeticException if the duration exceeds the capacity of the implementation.
118     *
119     * @see java.time.Duration#between(Temporal, Temporal)
120     */
121    @UML(identifier="TM_Separation.distance", obligation=OPTIONAL, specification=ISO_19108)
122    default TemporalAmount distance(TemporalPrimitive other) {
123        throw new UnsupportedOperationException();
124    }
125}