1   /* Copyright 2002-2025 CS GROUP
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.hipparchus.CalculusFieldElement;
20  
21  /** Interface for time scales.
22   * <p>This is the interface representing all time scales. Time scales are related
23   * to each other by some offsets that may be discontinuous (for example
24   * the {@link UTCScale UTC scale} with respect to the {@link TAIScale
25   * TAI scale}).</p>
26   * @author Luc Maisonobe
27   * @see AbsoluteDate
28   */
29  public interface TimeScale {
30  
31      /** Get the offset to convert locations from {@link TAIScale} to instance.
32       * @param date conversion date
33       * @return offset in seconds to add to a location in <em>{@link TAIScale}
34       * time scale</em> to get a location in <em>instance time scale</em>
35       * @see #offsetToTAI(DateComponents, TimeComponents)
36       */
37      TimeOffset offsetFromTAI(AbsoluteDate date);
38  
39      /** Get the offset to convert locations from {@link TAIScale} to instance.
40       * @param date conversion date
41       * @param <T> type of the filed elements
42       * @return offset in seconds to add to a location in <em>{@link TAIScale}
43       * time scale</em> to get a location in <em>instance time scale</em>
44       * @see #offsetToTAI(DateComponents, TimeComponents)
45       * @since 9.0
46       */
47      <T extends CalculusFieldElement<T>> T offsetFromTAI(FieldAbsoluteDate<T> date);
48  
49      /** Get the offset to convert locations from instance to {@link TAIScale}.
50       * @param date date location in the time scale
51       * @param time time location in the time scale
52       * @return offset in seconds to add to a location in <em>instance time scale</em>
53       * to get a location in <em>{@link TAIScale} time scale</em>
54       * @see #offsetFromTAI(AbsoluteDate)
55       */
56      default TimeOffset offsetToTAI(final DateComponents date, final TimeComponents time) {
57          final AbsoluteDate reference = new AbsoluteDate(date, time, new TAIScale());
58          TimeOffset offset = TimeOffset.ZERO;
59          for (int i = 0; i < 8; i++) {
60              offset = offsetFromTAI(reference.shiftedBy(offset)).negate();
61          }
62          return offset;
63      }
64  
65      /** Check if date is within a leap second introduction <em>in this time scale</em>.
66       * <p>
67       * This method will return false for all time scales that do <em>not</em>
68       * implement leap seconds, even if the date corresponds to a leap second
69       * in {@link UTCScale UTC scale}.
70       * </p>
71       * @param date date to check
72       * @return true if time is within a leap second introduction
73       */
74      default boolean insideLeap(final AbsoluteDate date) {
75          return false;
76      }
77  
78      /** Check if date is within a leap second introduction <em>in this time scale</em>.
79       * <p>
80       * This method will return false for all time scales that do <em>not</em>
81       * implement leap seconds, even if the date corresponds to a leap second
82       * in {@link UTCScale UTC scale}.
83       * </p>
84       * @param date date to check
85       * @param <T> type of the filed elements
86       * @return true if time is within a leap second introduction
87       * @since 9.0
88       */
89      default <T extends CalculusFieldElement<T>> boolean insideLeap(final FieldAbsoluteDate<T> date) {
90          return false;
91      }
92  
93      /** Check length of the current minute <em>in this time scale</em>.
94       * <p>
95       * This method will return 60 for all time scales that do <em>not</em>
96       * implement leap seconds, even if the date corresponds to a leap second
97       * in {@link UTCScale UTC scale}, and 61 for time scales that do implement
98       * leap second when the current date is within the last minute before the
99       * leap, or during the leap itself.
100      * </p>
101      * @param date date to check
102      * @return 60 or 61 depending on leap seconds introduction
103      */
104     default int minuteDuration(final AbsoluteDate date) {
105         return 60;
106     }
107 
108     /** Check length of the current minute <em>in this time scale</em>.
109      * <p>
110      * This method will return 60 for all time scales that do <em>not</em>
111      * implement leap seconds, even if the date corresponds to a leap second
112      * in {@link UTCScale UTC scale}, and 61 for time scales that do implement
113      * leap second when the current date is within the last minute before the
114      * leap, or during the leap itself.
115      * </p>
116      * @param date date to check
117      * @param <T> type of the filed elements
118      * @return 60 or 61 depending on leap seconds introduction
119      * @since 9.0
120      */
121     default <T extends CalculusFieldElement<T>> int minuteDuration(final FieldAbsoluteDate<T> date) {
122         return 60;
123     }
124 
125     /** Get the value of the previous leap.
126      * <p>
127      * This method will return 0 for all time scales that do <em>not</em>
128      * implement leap seconds.
129      * </p>
130      * @param date date to check
131      * @return value of the previous leap
132      */
133     default TimeOffset getLeap(final AbsoluteDate date) {
134         return TimeOffset.ZERO;
135     }
136 
137     /** Get the value of the previous leap.
138      * <p>
139      * This method will return 0.0 for all time scales that do <em>not</em>
140      * implement leap seconds.
141      * </p>
142      * @param date date to check
143      * @param <T> type of the filed elements
144      * @return value of the previous leap
145      * @since 9.0
146      */
147     default <T extends CalculusFieldElement<T>> T getLeap(final FieldAbsoluteDate<T> date) {
148         return date.getField().getZero();
149     }
150 
151     /** Get the name time scale.
152      * @return name of the time scale
153      */
154     String getName();
155 
156 }