1 //==============================================================================
2 //
3 //  This file is part of GPSTk, the GPS Toolkit.
4 //
5 //  The GPSTk is free software; you can redistribute it and/or modify
6 //  it under the terms of the GNU Lesser General Public License as published
7 //  by the Free Software Foundation; either version 3.0 of the License, or
8 //  any later version.
9 //
10 //  The GPSTk is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU Lesser General Public License for more details.
14 //
15 //  You should have received a copy of the GNU Lesser General Public
16 //  License along with GPSTk; if not, write to the Free Software Foundation,
17 //  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 //  This software was developed by Applied Research Laboratories at the
20 //  University of Texas at Austin.
21 //  Copyright 2004-2020, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 //  This software was developed by Applied Research Laboratories at the
28 //  University of Texas at Austin, under contract to an agency or agencies
29 //  within the U.S. Department of Defense. The U.S. Government retains all
30 //  rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 //  Pursuant to DoD Directive 523024
33 //
34 //  DISTRIBUTION STATEMENT A: This software has been approved for public
35 //                            release, distribution is unlimited.
36 //
37 //==============================================================================
38 
39 #include "BasicFramework.hpp"
40 
41 #include "TimeString.hpp"
42 #include "TimeConstants.hpp"
43 
44 #include "ANSITime.hpp"
45 #include "CivilTime.hpp"
46 #include "GPSWeekSecond.hpp"
47 #include "GPSWeekZcount.hpp"
48 #include "JulianDate.hpp"
49 #include "MJD.hpp"
50 #include "UnixTime.hpp"
51 #include "YDSTime.hpp"
52 #include "SystemTime.hpp"
53 
54 #include "CommandOptionWithCommonTimeArg.hpp"
55 
56 using namespace std;
57 using namespace gpstk;
58 
59 class TimCvt : public BasicFramework
60 {
61 public:
62    TimCvt(char* arg0);
63 
64 protected:
65    virtual void process();
66 
67 private:
68    CommandOptionWithCommonTimeArg ANSITimeOption;
69    CommandOptionWithCommonTimeArg CivilTimeOption;
70    CommandOptionWithCommonTimeArg RinexFileTimeOption;
71    CommandOptionWithCommonTimeArg GPSEWSOption;
72    CommandOptionWithCommonTimeArg GPSWSOption;
73    CommandOptionWithCommonTimeArg GPSWZOption;
74    CommandOptionWithCommonTimeArg GPSZ29Option;
75    CommandOptionWithCommonTimeArg GPSZ32Option;
76    CommandOptionWithCommonTimeArg JDOption;
77    CommandOptionWithCommonTimeArg MJDOption;
78    CommandOptionWithCommonTimeArg UnixTimeOption;
79    CommandOptionWithCommonTimeArg YDSTimeOption;
80 
81    CommandOptionWithAnyArg inputFormatOption;
82    CommandOptionWithAnyArg inputTimeOption;
83    CommandOptionAllOf inputFormatAndTimeOption;
84 
85    CommandOptionWithAnyArg formatOption;
86    CommandOptionWithNumberArg addOption;
87    CommandOptionWithNumberArg subOption;
88    CommandOptionMutex mutexOption;
89 
90    string stringToParse;
91    string timeSpec;
92 };
93 
TimCvt(char * arg0)94 TimCvt::TimCvt(char* arg0)
95       : BasicFramework(arg0, "Converts from a given input time specification"
96                        " to other time formats.  Include the quotation marks."
97                        "  All year values are four digit years."),
98         ANSITimeOption('A', "ansi", "%K", "\"ANSI-Second\""),
99         CivilTimeOption('c', "civil", "%m %d %Y %H:%M:%f",
100                         "\"Month(numeric) DayOfMonth Year Hour:Minute:Second\""),
101         RinexFileTimeOption('R', "rinex-file", "%y %m %d %H %M %S",
102                             "\"Year(2-digit) Month(numeric) DayOfMonth Hour Minute Second\""),
103         GPSEWSOption('o', "ews", "%E %G %g",
104                      "\"GPSEpoch 10bitGPSweek SecondOfWeek\""),
105         GPSWSOption('f', "ws", "%F %g", "\"FullGPSWeek SecondOfWeek\""),
106         GPSWZOption('w', "wz", "%F %Z", "\"FullGPSWeek Zcount\""),
107         GPSZ29Option(0, "z29", "%E %c", "\"29bitZcount\""),
108         GPSZ32Option('Z', "z32", "%C", "\"32bitZcount\""),
109         JDOption('j', "julian", "%J", "\"JulianDate\""),
110         MJDOption('m', "mjd", "%Q", "\"ModifiedJulianDate\""),
111         UnixTimeOption('u',"unixtime", "%U %u",
112                        "\"UnixSeconds UnixMicroseconds\""),
113         YDSTimeOption('y', "doy", "%Y %j %s",
114                       "\"Year DayOfYear SecondsOfDay\""),
115         inputFormatOption(0, "input-format", "Time format to use on input"),
116         inputTimeOption(0, "input-time",
117                         "Time to be parsed by \"input-format\" option"),
118         formatOption('F', "format", "Time format to use on output"),
119         addOption('a', "add-offset", "add NUM seconds to specified time"),
120         subOption('s', "sub-offset",
121                   "subtract NUM seconds from specified time")
122 {
123    ANSITimeOption.setMaxCount(1);
124    CivilTimeOption.setMaxCount(1);
125    RinexFileTimeOption.setMaxCount(1);
126    GPSEWSOption.setMaxCount(1);
127    GPSWSOption.setMaxCount(1);
128    GPSWZOption.setMaxCount(1);
129    GPSZ29Option.setMaxCount(1);
130    GPSZ32Option.setMaxCount(1);
131    JDOption.setMaxCount(1);
132    MJDOption.setMaxCount(1);
133    UnixTimeOption.setMaxCount(1);
134    YDSTimeOption.setMaxCount(1);
135    formatOption.setMaxCount(1);
136 
137    inputFormatOption.setMaxCount(1);
138    inputTimeOption.setMaxCount(1);
139    inputFormatAndTimeOption.addOption(&inputFormatOption);
140    inputFormatAndTimeOption.addOption(&inputTimeOption);
141 
142    mutexOption.addOption(&ANSITimeOption);
143    mutexOption.addOption(&CivilTimeOption);
144    mutexOption.addOption(&RinexFileTimeOption);
145    mutexOption.addOption(&GPSEWSOption);
146    mutexOption.addOption(&GPSWSOption);
147    mutexOption.addOption(&GPSWZOption);
148    mutexOption.addOption(&GPSZ29Option);
149    mutexOption.addOption(&GPSZ32Option);
150    mutexOption.addOption(&JDOption);
151    mutexOption.addOption(&MJDOption);
152    mutexOption.addOption(&UnixTimeOption);
153    mutexOption.addOption(&YDSTimeOption);
154    mutexOption.addOption(&inputFormatAndTimeOption);
155 }
156 
process()157 void TimCvt::process()
158 {
159    CommonTime ct;
160    ct.setTimeSystem(TimeSystem::GPS);
161    CommandOption *whichOpt = mutexOption.whichOne();
162 
163    if (whichOpt)
164    {
165       CommandOptionWithCommonTimeArg *cta =
166          dynamic_cast<CommandOptionWithCommonTimeArg *>(whichOpt);
167       if (cta)
168       {
169          ct = cta->getTime().front();
170          ct.setTimeSystem(TimeSystem::GPS);
171       }
172       else // whichOpt == &inputFormatAndTimeOption
173       {
174          mixedScanTime( ct,
175                         inputTimeOption.getValue().front(),
176                         inputFormatOption.getValue().front() );
177          ct.setTimeSystem(TimeSystem::GPS);
178       }
179    }
180    else
181    {
182       ct = SystemTime();
183       ct.setTimeSystem(TimeSystem::GPS);
184    }
185 
186    int i;
187    int addOptions = addOption.getCount();
188    int subOptions = subOption.getCount();
189    for (i = 0; i < addOptions; i++)
190       ct += StringUtils::asDouble(addOption.getValue()[i]);
191    for (i = 0; i < subOptions; i++)
192       ct -= StringUtils::asDouble(subOption.getValue()[i]);
193 
194    if (formatOption.getCount())
195    {
196       cout << printTime(ct, formatOption.getValue()[0]) << endl;
197    }
198    else
199    {
200       using StringUtils::leftJustify;
201       string eight(8, ' '); // eight spaces
202 
203       GPSWeekZcount wz(ct);
204       CivilTime civ(ct);
205 
206       cout << endl
207            << eight << leftJustify("Month/Day/Year H:M:S", 32)
208            << CivilTime(ct).printf("%02m/%02d/%04Y %02H:%02M:%02S") << endl
209 
210            << eight << leftJustify("Modified Julian Date", 32)
211            << setprecision(15) << MJD(ct).printf("%15.9Q") << endl
212 
213            << eight << leftJustify("GPSweek DayOfWeek SecOfWeek", 32)
214            << GPSWeekSecond(ct).printf("%G %w % 13.6g") << endl
215 
216            << eight << leftJustify("FullGPSweek Zcount", 32)
217            << wz.printf("%F % 6z") << endl
218 
219            << eight << leftJustify("Year DayOfYear SecondOfDay", 32)
220            << YDSTime(ct).printf("%Y %03j % 12.6s") << endl
221 
222            << eight << leftJustify("Unix: Second Microsecond", 32)
223            << UnixTime(ct).printf("%U % 6u") << endl
224 
225            << eight << leftJustify("Zcount: 29-bit (32-bit)", 32)
226            << wz.printf("%c (%C)") << endl
227 
228            << endl << endl;
229    }
230 
231    return;
232 }
233 
main(int argc,char * argv[])234 int main(int argc, char* argv[])
235 {
236    try
237    {
238       TimCvt m(argv[0]);
239       if (!m.initialize(argc, argv))
240          return m.exitCode;
241       if (!m.run())
242          return m.exitCode;
243 
244       return m.exitCode;
245    }
246    catch(Exception& e)
247    {
248       cout << e << endl;
249    }
250    catch(std::exception& e)
251    {
252       cout << e.what() << endl;
253    }
254    catch(...)
255    {
256       cout << "unknown error" << endl;
257    }
258       // only reach this point if an exception was caught
259    return BasicFramework::EXCEPTION_ERROR;
260 }
261