UTCTAIOffset.java

  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. import java.io.Serializable;

  19. import org.orekit.utils.Constants;

  20. /** Offset between {@link UTCScale UTC} and  {@link TAIScale TAI} time scales.
  21.  * <p>The {@link UTCScale UTC} and  {@link TAIScale TAI} time scales are two
  22.  * scales offset with respect to each other. The {@link TAIScale TAI} scale is
  23.  * continuous whereas the {@link UTCScale UTC} includes some discontinuity when
  24.  * leap seconds are introduced by the <a href="http://www.iers.org/">International
  25.  * Earth Rotation Service</a> (IERS).</p>
  26.  * <p>This class represents the offset between the two scales that is
  27.  * valid between two leap seconds occurrences. It handles both the linear offsets
  28.  * used from 1961-01-01 to 1971-12-31 and the constant integer offsets used since
  29.  * 1972-01-01.</p>
  30.  * @author Luc Maisonobe
  31.  * @see UTCScale
  32.  * @see UTCTAIHistoryFilesLoader
  33.  */
  34. class UTCTAIOffset implements TimeStamped, Serializable {

  35.     /** Serializable UID. */
  36.     private static final long serialVersionUID = 4742190573136348054L;

  37.     /** Leap date. */
  38.     private final AbsoluteDate leapDate;

  39.     /** Leap date in Modified Julian Day. */
  40.     private final int leapDateMJD;

  41.     /** Offset start of validity date. */
  42.     private final AbsoluteDate validityStart;

  43.     /** Offset end of validity date. */
  44.     private AbsoluteDate validityEnd;

  45.     /** Reference date for the slope multiplication as Modified Julian Day. */
  46.     private final int mjdRef;

  47.     /** Reference date for the slope multiplication. */
  48.     private final AbsoluteDate reference;

  49.     /** Value of the leap at offset validity start (in seconds). */
  50.     private final double leap;

  51.     /** Offset at validity start in seconds (TAI minus UTC). */
  52.     private final double offset;

  53.     /** Offset slope in seconds per UTC second (TAI minus UTC / dUTC). */
  54.     private final double slopeUTC;

  55.     /** Offset slope in seconds per TAI second (TAI minus UTC / dTAI). */
  56.     private final double slopeTAI;

  57.     /** Simple constructor for a constant model.
  58.      * @param leapDate leap date
  59.      * @param leapDateMJD leap date in Modified Julian Day
  60.      * @param leap value of the leap at offset validity start (in seconds)
  61.      * @param offset offset in seconds (TAI minus UTC)
  62.      */
  63.     public UTCTAIOffset(final AbsoluteDate leapDate, final int leapDateMJD,
  64.                         final double leap, final double offset) {
  65.         this(leapDate, leapDateMJD, leap, offset, 0, 0);
  66.     }

  67.     /** Simple constructor for a linear model.
  68.      * @param leapDate leap date
  69.      * @param leapDateMJD leap date in Modified Julian Day
  70.      * @param leap value of the leap at offset validity start (in seconds)
  71.      * @param offset offset in seconds (TAI minus UTC)
  72.      * @param mjdRef reference date for the slope multiplication as Modified Julian Day
  73.      * @param slope offset slope in seconds per UTC second (TAI minus UTC / dUTC)
  74.      */
  75.     public UTCTAIOffset(final AbsoluteDate leapDate, final int leapDateMJD,
  76.                         final double leap, final double offset,
  77.                         final int mjdRef, final double slope) {
  78.         this.leapDate      = leapDate;
  79.         this.leapDateMJD   = leapDateMJD;
  80.         this.validityStart = leapDate.shiftedBy(leap);
  81.         this.validityEnd   = AbsoluteDate.FUTURE_INFINITY;
  82.         this.mjdRef        = mjdRef;
  83.         this.reference     = new AbsoluteDate(new DateComponents(DateComponents.MODIFIED_JULIAN_EPOCH, mjdRef),
  84.                                               TimeScalesFactory.getTAI()).shiftedBy(offset);
  85.         this.leap          = leap;
  86.         this.offset        = offset;
  87.         this.slopeUTC      = slope;
  88.         this.slopeTAI      = slope / (1 + slope);
  89.     }

  90.     /** Get the date of the start of the leap.
  91.      * @return date of the start of the leap
  92.      * @see #getValidityStart()
  93.      */
  94.     public AbsoluteDate getDate() {
  95.         return leapDate;
  96.     }

  97.     /** Get the date of the start of the leap as Modified Julian Day.
  98.      * @return date of the start of the leap as Modified Julian Day
  99.      */
  100.     public int getMJD() {
  101.         return leapDateMJD;
  102.     }

  103.     /** Get the start time of validity for this offset.
  104.      * <p>The start of the validity of the offset is {@link #getLeap()}
  105.      * seconds after the start of the leap itself.</p>
  106.      * @return start of validity date
  107.      * @see #getDate()
  108.      * @see #getValidityEnd()
  109.      */
  110.     public AbsoluteDate getValidityStart() {
  111.         return validityStart;
  112.     }

  113.     /** Get the end time of validity for this offset.
  114.      * <p>The end of the validity of the offset is the date of the
  115.      * start of the leap leading to the next offset.</p>
  116.      * @return end of validity date
  117.      * @see #getValidityStart()
  118.      */
  119.     public AbsoluteDate getValidityEnd() {
  120.         return validityEnd;
  121.     }

  122.     /** Set the end time of validity for this offset.
  123.      * @param validityEnd end of validity date
  124.      * @see #getValidityEnd()
  125.      */
  126.     void setValidityEnd(final AbsoluteDate validityEnd) {
  127.         this.validityEnd = validityEnd;
  128.     }

  129.     /** Get the value of the leap at offset validity start (in seconds).
  130.      * @return value of the leap at offset validity start (in seconds)
  131.      */
  132.     public double getLeap() {
  133.         return leap;
  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.     /** Get the TAI - UTC offset in seconds.
  143.      * @param date date components (in UTC) at which the offset is requested
  144.      * @param time time components (in UTC) at which the offset is requested
  145.      * @return TAI - UTC offset in seconds.
  146.      */
  147.     public double getOffset(final DateComponents date, final TimeComponents time) {
  148.         final int    days     = date.getMJD() - mjdRef;
  149.         final double fraction = time.getSecondsInDay();
  150.         return offset + days * (slopeUTC * Constants.JULIAN_DAY) + fraction * slopeUTC;
  151.     }

  152. }