1   /* Copyright 2022-2025 Romain Serra
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.time;
18  
19  /**
20   * Interface representing a closed time interval i.e. [a, b], possibly of infinite length.
21   *
22   * @author Romain Serra
23   * @since 13.1
24   * @see AbsoluteDate
25   */
26  public interface TimeInterval {
27  
28      /**
29       * Getter for the left end of the interval.
30       * @return left end
31       */
32      AbsoluteDate getStartDate();
33  
34      /**
35       * Getter for the right end of the interval.
36       * @return right end
37       */
38      AbsoluteDate getEndDate();
39  
40      /**
41       * Computes the interval length in seconds.
42       * @return duration
43       */
44      default double duration() {
45          return getEndDate().durationFrom(getStartDate());
46      }
47  
48      /**
49       * Method returning true if and only if the dated input is contained within the closed interval.
50       * @param timeStamped time stamped object
51       * @return boolean on inclusion
52       */
53      default boolean contains(final TimeStamped timeStamped) {
54          final AbsoluteDate date = timeStamped.getDate();
55          return getStartDate().isBeforeOrEqualTo(date) && getEndDate().isAfterOrEqualTo(date);
56      }
57  
58      /**
59       * Method returning true if and only if input (also a closed time interval) contains the instance.
60       * @param interval time interval
61       * @return boolean on inclusion
62       */
63      default boolean contains(final TimeInterval interval) {
64          return (getEndDate().isAfterOrEqualTo(interval.getEndDate())) && (getStartDate().isBeforeOrEqualTo(interval.getStartDate()));
65      }
66  
67      /**
68       * Method returning true if and only if input (also a closed time interval) intersects the instance.
69       * @param interval time interval
70       * @return boolean on intersection
71       */
72      default boolean intersects(final TimeInterval interval) {
73          return (getEndDate().isAfterOrEqualTo(interval.getStartDate())) && (getStartDate().isBeforeOrEqualTo(interval.getEndDate()));
74      }
75  
76      /**
77       * Create instance from two dates in arbitrary order.
78       * @param date date
79       * @param otherDate other date
80       * @return time interval
81       */
82      static TimeInterval of(final AbsoluteDate date, final AbsoluteDate otherDate) {
83          if (otherDate.isBefore(date)) {
84              return of(otherDate, date);
85          }
86          return new TimeInterval() {
87  
88              @Override
89              public AbsoluteDate getStartDate() {
90                  return date;
91              }
92  
93              @Override
94              public AbsoluteDate getEndDate() {
95                  return otherDate;
96              }
97          };
98      }
99  
100     /**
101      * Create instance from two dates in arbitrary order.
102      * @param date start (or end) date
103      * @param duration duration, in seconds (if positive, time interval is from date to date + duration,
104      *                 if negative, the time interval will be from date - duration to date)
105      * @return time interval
106      * @since 14.0
107      */
108     static TimeInterval of(final AbsoluteDate date, final double duration) {
109         if (duration < 0.0) {
110             return of(date.shiftedBy(duration), date);
111         }
112         return of(date, date.shiftedBy(duration));
113     }
114 }