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 /** Reference date for the slope multiplication as Modified Julian Day. */ 52 private final int mjdRef; 53 54 /** Reference date for the slope multiplication. */ 55 private final AbsoluteDate reference; 56 57 /** Value of the leap at offset validity start (in seconds). */ 58 private final double leap; 59 60 /** Offset at validity start in seconds (TAI minus UTC). */ 61 private final double offset; 62 63 /** Offset slope in seconds per UTC second (TAI minus UTC / dUTC). */ 64 private final double slopeUTC; 65 66 /** Offset slope in seconds per TAI second (TAI minus UTC / dTAI). */ 67 private final double slopeTAI; 68 69 /** Simple constructor for a constant model. 70 * @param leapDate leap date 71 * @param leapDateMJD leap date in Modified Julian Day 72 * @param leap value of the leap at offset validity start (in seconds) 73 * @param offset offset in seconds (TAI minus UTC) 74 */ 75 UTCTAIOffset(final AbsoluteDate leapDate, final int leapDateMJD, 76 final double leap, final double offset) { 77 this(leapDate, leapDateMJD, leap, offset, 0, 0); 78 } 79 80 /** Simple constructor for a linear model. 81 * @param leapDate leap date 82 * @param leapDateMJD leap date in Modified Julian Day 83 * @param leap value of the leap at offset validity start (in seconds) 84 * @param offset offset in seconds (TAI minus UTC) 85 * @param mjdRef reference date for the slope multiplication as Modified Julian Day 86 * @param slope offset slope in seconds per UTC second (TAI minus UTC / dUTC) 87 */ 88 UTCTAIOffset(final AbsoluteDate leapDate, final int leapDateMJD, 89 final double leap, final double offset, 90 final int mjdRef, final double slope) { 91 this.leapDate = leapDate; 92 this.leapDateMJD = leapDateMJD; 93 this.validityStart = leapDate.shiftedBy(leap); 94 this.mjdRef = mjdRef; 95 this.reference = new AbsoluteDate(new DateComponents(DateComponents.MODIFIED_JULIAN_EPOCH, mjdRef), 96 TimeScalesFactory.getTAI()).shiftedBy(offset); 97 this.leap = leap; 98 this.offset = offset; 99 this.slopeUTC = slope; 100 this.slopeTAI = slope / (1 + slope); 101 } 102 103 /** Get the date of the start of the leap. 104 * @return date of the start of the leap 105 * @see #getValidityStart() 106 */ 107 public AbsoluteDate getDate() { 108 return leapDate; 109 } 110 111 /** Get the date of the start of the leap as Modified Julian Day. 112 * @return date of the start of the leap as Modified Julian Day 113 */ 114 public int getMJD() { 115 return leapDateMJD; 116 } 117 118 /** Get the start time of validity for this offset. 119 * <p>The start of the validity of the offset is {@link #getLeap()} 120 * seconds after the start of the leap itself.</p> 121 * @return start of validity date 122 * @see #getDate() 123 */ 124 public AbsoluteDate getValidityStart() { 125 return validityStart; 126 } 127 128 /** Get the value of the leap at offset validity start (in seconds). 129 * @return value of the leap at offset validity start (in seconds) 130 */ 131 public double getLeap() { 132 return leap; 133 } 134 135 /** Get the TAI - UTC offset in seconds. 136 * @param date date at which the offset is requested 137 * @return TAI - UTC offset in seconds. 138 */ 139 public double getOffset(final AbsoluteDate date) { 140 return offset + date.durationFrom(reference) * slopeTAI; 141 } 142 143 /** Get the TAI - UTC offset in seconds. 144 * @param date date components (in UTC) at which the offset is requested 145 * @param time time components (in UTC) at which the offset is requested 146 * @return TAI - UTC offset in seconds. 147 */ 148 public double getOffset(final DateComponents date, final TimeComponents time) { 149 final int days = date.getMJD() - mjdRef; 150 final double fraction = time.getSecondsInUTCDay(); 151 return offset + days * (slopeUTC * Constants.JULIAN_DAY) + fraction * slopeUTC; 152 } 153 154 }