1   /* Contributed in the public domain.
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.files.ccsds;
18  
19  import org.orekit.errors.OrekitException;
20  import org.orekit.errors.OrekitMessages;
21  import org.orekit.time.AbsoluteDate;
22  import org.orekit.time.DateTimeComponents;
23  import org.orekit.time.TimeScale;
24  import org.orekit.time.TimeScalesFactory;
25  import org.orekit.utils.Constants;
26  import org.orekit.utils.IERSConventions;
27  
28  /**
29   * The set of time scales defined in Annex A of the ODM CCSDS standard 502.0-B-2.
30   *
31   * @author Evan Ward
32   */
33  public enum CcsdsTimeScale {
34  
35      /** Greenwich Mean Sidereal Time. */
36      GMST {
37          @Override
38          public TimeScale getTimeScale(final IERSConventions conventions) {
39              return TimeScalesFactory.getGMST(conventions, false);
40          }
41      },
42      /** Global Positioning System. */
43      GPS {
44          @Override
45          public TimeScale getTimeScale(final IERSConventions conventions) {
46              return TimeScalesFactory.getGPS();
47          }
48      },
49      /** Mission Elapsed Time. */
50      MET {
51          @Override
52          public AbsoluteDate parseDate(final String date,
53                                        final IERSConventions conventions,
54                                        final AbsoluteDate missionReferenceDate) {
55              final DateTimeComponents clock = DateTimeComponents.parseDateTime(date);
56              final double offset = clock.getDate().getYear() * Constants.JULIAN_YEAR +
57                      clock.getDate().getDayOfYear() * Constants.JULIAN_DAY +
58                      clock.getTime().getSecondsInUTCDay();
59              return missionReferenceDate.shiftedBy(offset);
60          }
61  
62          @Override
63          public TimeScale getTimeScale(final IERSConventions conventions) {
64              throw new OrekitException(
65                      OrekitMessages.CCSDS_NO_CORRESPONDING_TIME_SCALE,
66                      "MET");
67          }
68      },
69      /** Mission Relative Time. */
70      MRT {
71          @Override
72          public AbsoluteDate parseDate(final String date,
73                                        final IERSConventions conventions,
74                                        final AbsoluteDate missionReferenceDate) {
75              final DateTimeComponents clock = DateTimeComponents.parseDateTime(date);
76              final double offset = clock.getDate().getYear() * Constants.JULIAN_YEAR +
77                      clock.getDate().getDayOfYear() * Constants.JULIAN_DAY +
78                      clock.getTime().getSecondsInUTCDay();
79              return missionReferenceDate.shiftedBy(offset);
80          }
81  
82          @Override
83          public TimeScale getTimeScale(final IERSConventions conventions) {
84              throw new OrekitException(
85                      OrekitMessages.CCSDS_NO_CORRESPONDING_TIME_SCALE,
86                      "MRT");
87          }
88      },
89      /** Spacecraft Clock. Not currently Implemented. */
90      SCLK {
91          @Override
92          public AbsoluteDate parseDate(final String date,
93                                        final IERSConventions conventions,
94                                        final AbsoluteDate missionReferenceDate) {
95              throw new OrekitException(
96                      OrekitMessages.CCSDS_TIME_SYSTEM_NOT_IMPLEMENTED,
97                      this.name());
98          }
99  
100         @Override
101         public TimeScale getTimeScale(final IERSConventions conventions) {
102             throw new OrekitException(
103                     OrekitMessages.CCSDS_NO_CORRESPONDING_TIME_SCALE,
104                     this.name());
105         }
106     },
107     /** International Atomic Time. */
108     TAI {
109         @Override
110         public TimeScale getTimeScale(final IERSConventions conventions) {
111             return TimeScalesFactory.getTAI();
112         }
113     },
114     /** Barycentric Coordinate Time. */
115     TCB {
116         @Override
117         public TimeScale getTimeScale(final IERSConventions conventions) {
118             return TimeScalesFactory.getTCB();
119         }
120     },
121     /** Barycentric Dynamical Time. */
122     TDB {
123         @Override
124         public TimeScale getTimeScale(final IERSConventions conventions) {
125             return TimeScalesFactory.getTDB();
126         }
127     },
128     /** Geocentric Coordinate Time. */
129     TCG {
130         @Override
131         public TimeScale getTimeScale(final IERSConventions conventions) {
132             return TimeScalesFactory.getTCG();
133         }
134     },
135     /** Terrestrial Time. */
136     TT {
137         @Override
138         public TimeScale getTimeScale(final IERSConventions conventions) {
139             return TimeScalesFactory.getTT();
140         }
141     },
142     /** Universal Time. */
143     UT1 {
144         @Override
145         public TimeScale getTimeScale(final IERSConventions conventions) {
146             return TimeScalesFactory.getUT1(conventions, false);
147         }
148     },
149     /** Universal Coordinated Time. */
150     UTC {
151         @Override
152         public TimeScale getTimeScale(final IERSConventions conventions) {
153             return TimeScalesFactory.getUTC();
154         }
155     };
156 
157     /**
158      * Parse a date in this time scale.
159      *
160      * @param date                 a CCSDS date string.
161      * @param conventions          IERS conventions for {@link #UT1} and {@link #GMST}.
162      * @param missionReferenceDate epoch for {@link #MET} and {@link #MRT}.
163      * @return parsed {@code date}.
164      */
165     public AbsoluteDate parseDate(final String date,
166                                   final IERSConventions conventions,
167                                   final AbsoluteDate missionReferenceDate) {
168         return new AbsoluteDate(date, this.getTimeScale(conventions));
169     }
170 
171     /**
172      * Get the corresponding {@link TimeScale}.
173      *
174      * @param conventions IERS Conventions for the {@link #GMST} and {@link #UT1} scales.
175      * @return the time scale.
176      */
177     public abstract TimeScale getTimeScale(IERSConventions conventions);
178 
179     /**
180      * Check if {@code timeScale} is one of the values supported by this enum.
181      *
182      * @param timeScale specifier.
183      * @return {@code true} if {@link #valueOf(String)} will not throw an exception with
184      * the same string.
185      */
186     public static boolean contains(final String timeScale) {
187         for (final CcsdsTimeScale scale : values()) {
188             if (scale.name().equals(timeScale)) {
189                 return true;
190             }
191         }
192         return false;
193     }
194 
195 }