GPSDate.java

  1. /* Copyright 2002-2019 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.hipparchus.util.FastMath;
  20. import org.orekit.utils.Constants;

  21. /** Container for date in GPS form.
  22.  * @author Luc Maisonobe
  23.  * @see AbsoluteDate
  24.  * @since 9.3
  25.  */
  26. public class GPSDate implements Serializable, TimeStamped {

  27.     /** Serializable UID. */
  28.     private static final long serialVersionUID = 20180633L;

  29.     /** Duration of a week in seconds. */
  30.     private static final double WEEK = 7 * Constants.JULIAN_DAY;

  31.     /** conversion factor from seconds to milliseconds. */
  32.     private static final double S_TO_MS = 1000.0;

  33.     /** Week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}. */
  34.     private final int weekNumber;

  35.     /** Number of milliseconds since week start. */
  36.     private final double milliInWeek;

  37.     /** Corresponding date. */
  38.     private final transient AbsoluteDate date;

  39.     /** Build an instance corresponding to a GPS date.
  40.      * <p>GPS dates are provided as a week number starting at
  41.      * {@link AbsoluteDate#GPS_EPOCH GPS epoch} and as a number of milliseconds
  42.      * since week start.</p>
  43.      * @param weekNumber week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}
  44.      * @param milliInWeek number of milliseconds since week start
  45.      */
  46.     public GPSDate(final int weekNumber, final double milliInWeek) {

  47.         this.weekNumber  = weekNumber;
  48.         this.milliInWeek = milliInWeek;

  49.         final int day = (int) FastMath.floor(milliInWeek / (Constants.JULIAN_DAY * S_TO_MS));
  50.         final double secondsInDay = milliInWeek / S_TO_MS - day * Constants.JULIAN_DAY;
  51.         date = new AbsoluteDate(new DateComponents(DateComponents.GPS_EPOCH, weekNumber * 7 + day),
  52.                                 new TimeComponents(secondsInDay),
  53.                                 TimeScalesFactory.getGPS());

  54.     }

  55.     /** Build an instance from an absolute date.
  56.      * @param date absolute date to consider
  57.      */
  58.     public GPSDate(final AbsoluteDate date) {

  59.         this.weekNumber  = (int) FastMath.floor(date.durationFrom(AbsoluteDate.GPS_EPOCH) / WEEK);
  60.         final AbsoluteDate weekStart = new AbsoluteDate(AbsoluteDate.GPS_EPOCH, WEEK * weekNumber);
  61.         this.milliInWeek = date.durationFrom(weekStart) * S_TO_MS;
  62.         this.date        = date;

  63.     }

  64.     /** Get the week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}.
  65.      * @return week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}
  66.      */
  67.     public int getWeekNumber() {
  68.         return weekNumber;
  69.     }

  70.     /** Get the number of milliseconds since week start.
  71.      * @return number of milliseconds since week start
  72.      */
  73.     public double getMilliInWeek() {
  74.         return milliInWeek;
  75.     }

  76.     /** {@inheritDoc} */
  77.     @Override
  78.     public AbsoluteDate getDate() {
  79.         return date;
  80.     }

  81.     /** Replace the instance with a data transfer object for serialization.
  82.      * @return data transfer object that will be serialized
  83.      */
  84.     private Object writeReplace() {
  85.         return new DataTransferObject(weekNumber, milliInWeek);
  86.     }

  87.     /** Internal class used only for serialization. */
  88.     private static class DataTransferObject implements Serializable {

  89.         /** Serializable UID. */
  90.         private static final long serialVersionUID = 20180633L;

  91.         /** Week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}. */
  92.         private final int weekNumber;

  93.         /** Number of milliseconds since week start. */
  94.         private final double milliInWeek;

  95.         /** Simple constructor.
  96.          * @param weekNumber week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}
  97.          * @param milliInWeek number of milliseconds since week start
  98.          */
  99.         DataTransferObject(final int weekNumber, final double milliInWeek) {
  100.             this.weekNumber  = weekNumber;
  101.             this.milliInWeek = milliInWeek;
  102.         }

  103.         /** Replace the deserialized data transfer object with a {@link GPSDate}.
  104.          * @return replacement {@link GPSDate}
  105.          */
  106.         private Object readResolve() {
  107.             return new GPSDate(weekNumber, milliInWeek);
  108.         }

  109.     }

  110. }