1 /* Copyright 2002-2013 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 public 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 public 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.getSecondsInDay(); 174 return offset + days * (slopeUTC * Constants.JULIAN_DAY) + fraction * slopeUTC; 175 } 176 177 }