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
19 import java.io.Serializable;
20
21 import org.hipparchus.util.FastMath;
22 import org.orekit.utils.Constants;
23
24 /** Container for date in GPS form.
25 * @author Luc Maisonobe
26 * @see AbsoluteDate
27 * @since 9.3
28 */
29 public class GPSDate implements Serializable, TimeStamped {
30
31 /** Serializable UID. */
32 private static final long serialVersionUID = 20180633L;
33
34 /** Duration of a week in seconds. */
35 private static final double WEEK = 7 * Constants.JULIAN_DAY;
36
37 /** conversion factor from seconds to milliseconds. */
38 private static final double S_TO_MS = 1000.0;
39
40 /** Week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}. */
41 private final int weekNumber;
42
43 /** Number of milliseconds since week start. */
44 private final double milliInWeek;
45
46 /** Corresponding date. */
47 private final transient AbsoluteDate date;
48
49 /** Build an instance corresponding to a GPS date.
50 * <p>GPS dates are provided as a week number starting at
51 * {@link AbsoluteDate#GPS_EPOCH GPS epoch} and as a number of milliseconds
52 * since week start.</p>
53 * @param weekNumber week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}
54 * @param milliInWeek number of milliseconds since week start
55 */
56 public GPSDate(final int weekNumber, final double milliInWeek) {
57
58 this.weekNumber = weekNumber;
59 this.milliInWeek = milliInWeek;
60
61 final int day = (int) FastMath.floor(milliInWeek / (Constants.JULIAN_DAY * S_TO_MS));
62 final double secondsInDay = milliInWeek / S_TO_MS - day * Constants.JULIAN_DAY;
63 date = new AbsoluteDate(new DateComponents(DateComponents.GPS_EPOCH, weekNumber * 7 + day),
64 new TimeComponents(secondsInDay),
65 TimeScalesFactory.getGPS());
66
67 }
68
69 /** Build an instance from an absolute date.
70 * @param date absolute date to consider
71 */
72 public GPSDate(final AbsoluteDate date) {
73
74 this.weekNumber = (int) FastMath.floor(date.durationFrom(AbsoluteDate.GPS_EPOCH) / WEEK);
75 final AbsoluteDateteDate">AbsoluteDate weekStart = new AbsoluteDate(AbsoluteDate.GPS_EPOCH, WEEK * weekNumber);
76 this.milliInWeek = date.durationFrom(weekStart) * S_TO_MS;
77 this.date = date;
78
79 }
80
81 /** Get the week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}.
82 * @return week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}
83 */
84 public int getWeekNumber() {
85 return weekNumber;
86 }
87
88 /** Get the number of milliseconds since week start.
89 * @return number of milliseconds since week start
90 */
91 public double getMilliInWeek() {
92 return milliInWeek;
93 }
94
95 /** {@inheritDoc} */
96 @Override
97 public AbsoluteDate getDate() {
98 return date;
99 }
100
101 /** Replace the instance with a data transfer object for serialization.
102 * @return data transfer object that will be serialized
103 */
104 private Object writeReplace() {
105 return new DataTransferObject(weekNumber, milliInWeek);
106 }
107
108 /** Internal class used only for serialization. */
109 private static class DataTransferObject implements Serializable {
110
111 /** Serializable UID. */
112 private static final long serialVersionUID = 20180633L;
113
114 /** Week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}. */
115 private final int weekNumber;
116
117 /** Number of milliseconds since week start. */
118 private final double milliInWeek;
119
120 /** Simple constructor.
121 * @param weekNumber week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}
122 * @param milliInWeek number of milliseconds since week start
123 */
124 DataTransferObject(final int weekNumber, final double milliInWeek) {
125 this.weekNumber = weekNumber;
126 this.milliInWeek = milliInWeek;
127 }
128
129 /** Replace the deserialized data transfer object with a {@link GPSDate}.
130 * @return replacement {@link GPSDate}
131 */
132 private Object readResolve() {
133 return new GPSDate(weekNumber, milliInWeek);
134 }
135
136 }
137
138 }