1 /* Copyright 2002-2016 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.orekit.utils.Constants;
22
23 /** Offset between {@link UTCScale UTC} and {@link TAIScale TAI} time scales.
24 * <p>The {@link UTCScale UTC} and {@link TAIScale TAI} time scales are two
25 * scales offset with respect to each other. The {@link TAIScale TAI} scale is
26 * continuous whereas the {@link UTCScale UTC} includes some discontinuity when
27 * leap seconds are introduced by the <a href="http://www.iers.org/">International
28 * Earth Rotation Service</a> (IERS).</p>
29 * <p>This class represents the offset between the two scales that is
30 * valid between two leap seconds occurrences. It handles both the linear offsets
31 * used from 1961-01-01 to 1971-12-31 and the constant integer offsets used since
32 * 1972-01-01.</p>
33 * @author Luc Maisonobe
34 * @see UTCScale
35 * @see UTCTAIHistoryFilesLoader
36 */
37 class UTCTAIOffset implements TimeStamped, Serializable {
38
39 /** Serializable UID. */
40 private static final long serialVersionUID = 4742190573136348054L;
41
42 /** Leap date. */
43 private final AbsoluteDate leapDate;
44
45 /** Leap date in Modified Julian Day. */
46 private final int leapDateMJD;
47
48 /** Offset start of validity date. */
49 private final AbsoluteDate validityStart;
50
51 /** Offset end of validity date. */
52 private AbsoluteDate validityEnd;
53
54 /** Reference date for the slope multiplication as Modified Julian Day. */
55 private final int mjdRef;
56
57 /** Reference date for the slope multiplication. */
58 private final AbsoluteDate reference;
59
60 /** Value of the leap at offset validity start (in seconds). */
61 private final double leap;
62
63 /** Offset at validity start in seconds (TAI minus UTC). */
64 private final double offset;
65
66 /** Offset slope in seconds per UTC second (TAI minus UTC / dUTC). */
67 private final double slopeUTC;
68
69 /** Offset slope in seconds per TAI second (TAI minus UTC / dTAI). */
70 private final double slopeTAI;
71
72 /** Simple constructor for a constant model.
73 * @param leapDate leap date
74 * @param leapDateMJD leap date in Modified Julian Day
75 * @param leap value of the leap at offset validity start (in seconds)
76 * @param offset offset in seconds (TAI minus UTC)
77 */
78 UTCTAIOffset(final AbsoluteDate leapDate, final int leapDateMJD,
79 final double leap, final double offset) {
80 this(leapDate, leapDateMJD, leap, offset, 0, 0);
81 }
82
83 /** Simple constructor for a linear model.
84 * @param leapDate leap date
85 * @param leapDateMJD leap date in Modified Julian Day
86 * @param leap value of the leap at offset validity start (in seconds)
87 * @param offset offset in seconds (TAI minus UTC)
88 * @param mjdRef reference date for the slope multiplication as Modified Julian Day
89 * @param slope offset slope in seconds per UTC second (TAI minus UTC / dUTC)
90 */
91 UTCTAIOffset(final AbsoluteDate leapDate, final int leapDateMJD,
92 final double leap, final double offset,
93 final int mjdRef, final double slope) {
94 this.leapDate = leapDate;
95 this.leapDateMJD = leapDateMJD;
96 this.validityStart = leapDate.shiftedBy(leap);
97 this.validityEnd = AbsoluteDate.FUTURE_INFINITY;
98 this.mjdRef = mjdRef;
99 this.reference = new AbsoluteDate(new DateComponents(DateComponents.MODIFIED_JULIAN_EPOCH, mjdRef),
100 TimeScalesFactory.getTAI()).shiftedBy(offset);
101 this.leap = leap;
102 this.offset = offset;
103 this.slopeUTC = slope;
104 this.slopeTAI = slope / (1 + slope);
105 }
106
107 /** Get the date of the start of the leap.
108 * @return date of the start of the leap
109 * @see #getValidityStart()
110 */
111 public AbsoluteDate getDate() {
112 return leapDate;
113 }
114
115 /** Get the date of the start of the leap as Modified Julian Day.
116 * @return date of the start of the leap as Modified Julian Day
117 */
118 public int getMJD() {
119 return leapDateMJD;
120 }
121
122 /** Get the start time of validity for this offset.
123 * <p>The start of the validity of the offset is {@link #getLeap()}
124 * seconds after the start of the leap itself.</p>
125 * @return start of validity date
126 * @see #getDate()
127 * @see #getValidityEnd()
128 */
129 public AbsoluteDate getValidityStart() {
130 return validityStart;
131 }
132
133 /** Get the end time of validity for this offset.
134 * <p>The end of the validity of the offset is the date of the
135 * start of the leap leading to the next offset.</p>
136 * @return end of validity date
137 * @see #getValidityStart()
138 */
139 public AbsoluteDate getValidityEnd() {
140 return validityEnd;
141 }
142
143 /** Set the end time of validity for this offset.
144 * @param validityEnd end of validity date
145 * @see #getValidityEnd()
146 */
147 void setValidityEnd(final AbsoluteDate validityEnd) {
148 this.validityEnd = validityEnd;
149 }
150
151 /** Get the value of the leap at offset validity start (in seconds).
152 * @return value of the leap at offset validity start (in seconds)
153 */
154 public double getLeap() {
155 return leap;
156 }
157
158 /** Get the TAI - UTC offset in seconds.
159 * @param date date at which the offset is requested
160 * @return TAI - UTC offset in seconds.
161 */
162 public double getOffset(final AbsoluteDate date) {
163 return offset + date.durationFrom(reference) * slopeTAI;
164 }
165
166 /** Get the TAI - UTC offset in seconds.
167 * @param date date components (in UTC) at which the offset is requested
168 * @param time time components (in UTC) at which the offset is requested
169 * @return TAI - UTC offset in seconds.
170 */
171 public double getOffset(final DateComponents date, final TimeComponents time) {
172 final int days = date.getMJD() - mjdRef;
173 final double fraction = time.getSecondsInUTCDay();
174 return offset + days * (slopeUTC * Constants.JULIAN_DAY) + fraction * slopeUTC;
175 }
176
177 }