1 /* Copyright 2022-2026 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 import org.orekit.errors.OrekitException;
20 import org.orekit.errors.OrekitMessages;
21
22 /**
23 * Interface representing a closed time interval i.e. [a, b], possibly of infinite length.
24 *
25 * @author Romain Serra
26 * @since 13.1
27 * @see AbsoluteDate
28 */
29 public interface TimeInterval {
30
31 /** Interval covering the entire timeline
32 * from {@link AbsoluteDate#PAST_INFINITY} to {@link AbsoluteDate#FUTURE_INFINITY}.
33 * @since 14.0
34 */
35 TimeInterval UNLIMITED = TimeInterval.of(AbsoluteDate.PAST_INFINITY, AbsoluteDate.FUTURE_INFINITY, true);
36
37 /**
38 * Getter for the left end of the interval.
39 * @return left end
40 */
41 AbsoluteDate getStartDate();
42
43 /**
44 * Getter for the right end of the interval.
45 * @return right end
46 */
47 AbsoluteDate getEndDate();
48
49 /**
50 * Computes the interval length in seconds.
51 * @return duration
52 */
53 default double duration() {
54 return getEndDate().durationFrom(getStartDate());
55 }
56
57 /**
58 * Method returning true if and only if the dated input is contained within the closed interval.
59 * @param timeStamped time stamped object
60 * @return boolean on inclusion
61 */
62 default boolean contains(final TimeStamped timeStamped) {
63 final AbsoluteDate date = timeStamped.getDate();
64 return getStartDate().isBeforeOrEqualTo(date) && getEndDate().isAfterOrEqualTo(date);
65 }
66
67 /**
68 * Method returning true if and only if input (also a closed time interval) contains the instance.
69 * @param interval time interval
70 * @return boolean on inclusion
71 */
72 default boolean contains(final TimeInterval interval) {
73 return (getEndDate().isAfterOrEqualTo(interval.getEndDate())) && (getStartDate().isBeforeOrEqualTo(interval.getStartDate()));
74 }
75
76 /**
77 * Method returning true if and only if input (also a closed time interval) intersects the instance.
78 * @param interval time interval
79 * @return boolean on intersection
80 */
81 default boolean intersects(final TimeInterval interval) {
82 return (getEndDate().isAfterOrEqualTo(interval.getStartDate())) && (getStartDate().isBeforeOrEqualTo(interval.getEndDate()));
83 }
84
85 /**
86 * Create instance from two dates.
87 *
88 * @param date date
89 * @param otherDate other date
90 * @param allowNonChronological if true, the two dates can be in arbitrary order,
91 * they will be sorted internally. If false and {@code otherDate}
92 * is before {@code date}, then an exception is triggered
93 * @return time interval
94 * @since 14.0
95 */
96 static TimeInterval of(final AbsoluteDate date, final AbsoluteDate otherDate,
97 final boolean allowNonChronological) {
98
99 // check order
100 final AbsoluteDate start;
101 final AbsoluteDate end;
102 if (otherDate.isBefore(date)) {
103 if (allowNonChronological) {
104 // reorder dates
105 start = otherDate;
106 end = date;
107 } else {
108 throw new OrekitException(OrekitMessages.NON_CHRONOLOGICALLY_SORTED_ENTRIES,
109 date, otherDate, date.durationFrom(otherDate));
110 }
111 } else {
112 start = date;
113 end = otherDate;
114 }
115
116 // create instance
117 return new TimeInterval() {
118
119 /** {@inheritDoc} */
120 @Override
121 public AbsoluteDate getStartDate() {
122 return start;
123 }
124
125 /** {@inheritDoc} */
126 @Override
127 public AbsoluteDate getEndDate() {
128 return end;
129 }
130
131 };
132
133 }
134
135 /**
136 * Create instance from two dates in arbitrary order.
137 * @param date date
138 * @param otherDate other date
139 * @return time interval
140 */
141 static TimeInterval of(final AbsoluteDate date, final AbsoluteDate otherDate) {
142 return of(date, otherDate, true);
143 }
144
145 /**
146 * Create instance from two dates in arbitrary order.
147 * @param date start (or end) date
148 * @param duration duration, in seconds (if positive, time interval is from date to date + duration,
149 * if negative, the time interval will be from date - duration to date)
150 * @return time interval
151 * @since 14.0
152 */
153 static TimeInterval of(final AbsoluteDate date, final double duration) {
154 return of(date, date.shiftedBy(duration), true);
155 }
156
157 }