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