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 /// @file TimeString.cpp  print and scan using all TimeTag derived classes.
40 
41 #include "TimeString.hpp"
42 
43 #include "ANSITime.hpp"
44 #include "CivilTime.hpp"
45 #include "GPSWeekSecond.hpp"
46 #include "BDSWeekSecond.hpp"
47 #include "GALWeekSecond.hpp"
48 #include "QZSWeekSecond.hpp"
49 #include "IRNWeekSecond.hpp"
50 #include "GPSWeekZcount.hpp"
51 #include "JulianDate.hpp"
52 #include "MJD.hpp"
53 #include "UnixTime.hpp"
54 #include "PosixTime.hpp"
55 #include "YDSTime.hpp"
56 
57 #include "TimeConverters.hpp"
58 #include "TimeConstants.hpp"
59 
60 using namespace std;
61 
62 namespace gpstk
63 {
printTime(const CommonTime & t,const string & fmt)64    string printTime( const CommonTime& t,
65                           const string& fmt )
66    {
67       try
68       {
69          string rv( fmt );
70          try {rv = ANSITime(t).printf( rv );} catch (gpstk::InvalidRequest e){};
71          try {rv = CivilTime(t).printf( rv );} catch (gpstk::InvalidRequest e){};
72          try {rv = GPSWeekSecond(t).printf( rv );} catch (gpstk::InvalidRequest e){};
73          try {rv = GPSWeekZcount(t).printf( rv );} catch (gpstk::InvalidRequest e){};
74          try {rv = JulianDate(t).printf( rv );} catch (gpstk::InvalidRequest e){};
75          try {rv = MJD(t).printf( rv );} catch (gpstk::InvalidRequest e){};
76          try {rv = UnixTime(t).printf( rv );} catch (gpstk::InvalidRequest e){};
77          try {rv = PosixTime(t).printf( rv );} catch (gpstk::InvalidRequest e){};
78          try {rv = YDSTime(t).printf( rv );} catch (gpstk::InvalidRequest e){};
79          try {rv = GALWeekSecond(t).printf( rv );} catch (gpstk::InvalidRequest e){};
80          try {rv = BDSWeekSecond(t).printf( rv );} catch (gpstk::InvalidRequest e){};
81          try {rv = QZSWeekSecond(t).printf( rv );} catch (gpstk::InvalidRequest e){};
82          try {rv = IRNWeekSecond(t).printf( rv );} catch (gpstk::InvalidRequest e){};
83          return rv;
84       }
85       catch( gpstk::StringUtils::StringException& se )
86       {
87          GPSTK_RETHROW( se );
88       }
89    }
90 
91       /// Fill the TimeTag object \a btime with time information found in
92       /// string \a str formatted according to string \a fmt.
scanTime(TimeTag & btime,const string & str,const string & fmt)93    void scanTime( TimeTag& btime,
94                   const string& str,
95                   const string& fmt )
96    {
97       try
98       {
99             // Get the mapping of character (from fmt) to value (from str).
100          TimeTag::IdToValue info;
101          TimeTag::getInfo( str, fmt, info );
102 
103          if( btime.setFromInfo( info ) )
104          {
105             return;
106          }
107 
108             // Convert to CommonTime, and try to set using all formats.
109          CommonTime ct( btime.convertToCommonTime() );
110          scanTime( ct, str, fmt );
111 
112             // Convert the CommonTime into the requested format.
113          btime.convertFromCommonTime( ct );
114       }
115       catch( gpstk::InvalidRequest& ir )
116       {
117          GPSTK_RETHROW( ir );
118       }
119       catch( gpstk::StringUtils::StringException& se )
120       {
121          GPSTK_RETHROW( se );
122       }
123    }
124 
scanTime(CommonTime & t,const string & str,const string & fmt)125    void scanTime( CommonTime& t,
126                   const string& str,
127                   const string& fmt )
128    {
129       try
130       {
131          using namespace gpstk::StringUtils;
132 
133             // Get the mapping of character (from fmt) to value (from str).
134          TimeTag::IdToValue info;
135          TimeTag::getInfo( str, fmt, info );
136 
137             // These indicate which information has been found.
138          bool hmjd( false ), hsow( false ), hweek( false ), hfullweek( false ),
139             hdow( false ), hyear( false ), hmonth( false ), hday( false ),
140             hzcount( false ), hdoy( false ), hzcount29( false ),
141             hzcount32( false ), hhour( false ), hmin( false ), hsec( false ),
142             hsod( false ), hunixsec( false ), hunixusec( false ),
143             hepoch( false ), hansi( false ), hjulian( false ),
144             hbdsw( false ), hqzsw( false ), hgalw( false ), hirnw( false ),
145             hbdsfw( false ), hqzsfw( false ), hgalfw( false ), hirnfw( false ),
146             hbdse( false ), hqzse( false ), hgale( false), hirne( false ),
147             hposixsec( false ), hposixnsec( false );
148 
149             // These are to hold data that no one parses.
150          int idow(0);
151          TimeSystem ts;
152 
153          for( TimeTag::IdToValue::iterator itr = info.begin();
154               itr != info.end(); itr++ )
155          {
156             switch( itr->first )
157             {
158                case 'P':
159                   ts = gpstk::StringUtils::asTimeSystem(itr->second);
160                   t.setTimeSystem(ts);
161                   break;
162 
163                case 'Q':
164                   hmjd = true;
165                   break;
166 
167                case 'Z':
168                case 'z':
169                   hzcount = true;
170                   break;
171 
172                case 's':
173                   hsod = true;
174                   break;
175 
176                case 'g':
177                   hsow = true;
178                   break;
179 
180                case 'w':
181                   idow = asInt( itr->second );
182                   hdow = true;
183                   break;
184 
185                case 'G':
186                   hweek = true;
187                   break;
188 
189                case 'F':
190                   hfullweek = true;
191                   break;
192 
193                case 'j':
194                   hdoy = true;
195                   break;
196 
197                case 'b':
198                case 'B':
199                   hmonth = true;
200                   break;
201 
202                case 'Y':
203                case 'y':
204                   hyear = true;
205                   break;
206 
207                case 'a':
208                case 'A':
209                   {
210                      hdow = true;
211                      string thisDay = firstWord( itr->second );
212                      lowerCase(thisDay);
213                      if (isLike(thisDay, "sun.*")) idow = 0;
214                      else if (isLike(thisDay, "mon.*")) idow = 1;
215                      else if (isLike(thisDay, "tue.*")) idow = 2;
216                      else if (isLike(thisDay, "wed.*")) idow = 3;
217                      else if (isLike(thisDay, "thu.*")) idow = 4;
218                      else if (isLike(thisDay, "fri.*")) idow = 5;
219                      else if (isLike(thisDay, "sat.*")) idow = 6;
220                      else
221                      {
222                         hdow = false;
223                      }
224                   }
225                   break;
226 
227                case 'm':
228                   hmonth = true;
229                   break;
230 
231                case 'd':
232                   hday = true;
233                   break;
234 
235                case 'H':
236                   hhour = true;
237                   break;
238 
239                case 'M':
240                   hmin = true;
241                   break;
242 
243                case 'S':
244                   hsec = true;
245                   break;
246 
247                case 'f':
248                   hsec = true;
249                   // a small hack to make fractional seconds work
250                   info['S'] = info['f'];
251                   break;
252 
253                case 'U':
254                   hunixsec = true;
255                   break;
256 
257                case 'u':
258                   hunixusec = true;
259                   break;
260 
261                case 'W':
262                   hposixsec = true;
263                   break;
264 
265                case 'N':
266                   hposixnsec = true;
267                   break;
268 
269                case 'c':
270                   hzcount29 = true;
271                   break;
272 
273                case 'C':
274                   hzcount32 = true;
275                   break;
276 
277                case 'J':
278                   hjulian = true;
279                   break;
280 
281                case 'K':
282                   hansi = true;
283                   break;
284 
285                case 'E':
286                   hepoch = true;
287                   break;
288 
289                case 'R': hepoch = hbdse = true; break;
290                case 'T': hepoch = hgale = true; break;
291                case 'V': hepoch = hqzse = true; break;
292                case 'X': hepoch = hirne = true; break;
293 
294                case 'D': hfullweek = hbdsfw = true; break;
295                case 'e': hweek = hbdsw = true; break;
296                case 'L': hfullweek = hgalfw = true; break;
297                case 'l': hweek = hgalw = true; break;
298                case 'h': hfullweek = hqzsfw = true; break;
299                case 'i': hweek = hqzsw = true; break;
300                case 'O': hfullweek = hirnfw = true; break;
301                case 'o': hweek = hirnw = true; break;
302 
303 
304                default:
305                   {
306                      // do nothing
307                   }
308                   break;
309 
310             };
311          }     // end loop over Id/Value pairs
312 
313          if( hyear )
314          {
315             if( hmonth && hday )
316             {
317                CivilTime tt;
318                tt.setFromInfo( info );
319                if( hsod )
320                {
321                   convertSODtoTime( asDouble( info['s'] ),
322                                     tt.hour, tt.minute, tt.second );
323                }
324                t = tt.convertToCommonTime();
325                return;
326             }
327             else  // use YDSTime as default
328             {
329                YDSTime tt;
330                tt.setFromInfo( info );
331                if( hhour && hmin && hsec )
332                {
333                   tt.sod = convertTimeToSOD( asInt( info['H'] ),
334                                              asInt( info['M'] ),
335                                              asDouble( info['S'] ) );
336                }
337                t = tt.convertToCommonTime();
338                return;
339             }
340 
341          } // end of if( hyear )
342 
343          if( hzcount32 ||
344              (hfullweek && (hzcount || hzcount29)) ||
345              (hepoch && (hzcount29 ||
346                          (hweek && hzcount))) )
347          {
348             GPSWeekZcount tt;
349             tt.setFromInfo( info );
350             t = tt.convertToCommonTime();
351             return;
352          }
353 
354          if ( (hepoch && hweek) || hfullweek )
355          {
356             WeekSecond* ptt;
357             if(hbdse || hbdsfw || hbdsw) ptt = new BDSWeekSecond();
358             else if(hqzse || hqzsfw || hqzsw) ptt = new QZSWeekSecond();
359             else if(hgale || hgalfw || hgalw) ptt = new GALWeekSecond();
360             else if(hirne || hirnfw || hirnw) ptt = new IRNWeekSecond();
361             else ptt = new GPSWeekSecond();
362             ptt->setFromInfo(info);
363             if( hdow && !hsow )
364             {
365                ptt->sow = asInt( info['w'] ) * SEC_PER_DAY;
366                if( hsod )
367                {
368                   ptt->sow += asDouble( info['s'] );
369                }
370                else if( hhour && hmin && hsec )
371                {
372                   ptt->sow += convertTimeToSOD( asInt( info['H'] ),
373                                               asInt( info['M'] ),
374                                               asDouble( info['S'] ) );
375                }
376             }
377 
378             t = ptt->convertToCommonTime();
379             delete ptt;
380             return;
381          }
382 
383          if( hmjd )
384          {
385             MJD tt;
386             tt.setFromInfo( info );
387             t = tt.convertToCommonTime();
388             return;
389          }
390 
391          if( hjulian )
392          {
393             JulianDate tt;
394             tt.setFromInfo( info );
395             t = tt.convertToCommonTime();
396             return;
397          }
398 
399          if( hansi )
400          {
401             ANSITime tt;
402             tt.setFromInfo( info );
403             t = tt.convertToCommonTime();
404             return;
405          }
406 
407          if( hunixsec || hunixusec )
408          {
409             UnixTime tt;
410             tt.setFromInfo( info );
411             t = tt.convertToCommonTime();
412             return;
413          }
414 
415          if( hposixsec || hposixnsec )
416          {
417             PosixTime tt;
418             tt.setFromInfo( info );
419             t = tt.convertToCommonTime();
420             return;
421          }
422 
423          InvalidRequest ir("Incomplete time specification for readTime");
424          GPSTK_THROW( ir );
425       }
426       catch( gpstk::StringUtils::StringException& se )
427       {
428          GPSTK_RETHROW( se );
429       }
430    }
431 
mixedScanTime(CommonTime & t,const string & str,const string & fmt)432    void mixedScanTime( CommonTime& t,
433                        const string& str,
434                        const string& fmt )
435    {
436       try
437       {
438          using namespace gpstk::StringUtils;
439 
440             // Get the mapping of character (from fmt) to value (from str).
441          TimeTag::IdToValue info;
442          TimeTag::getInfo( str, fmt, info );
443 
444             // These indicate which information has been found.
445          bool hsow( false ), hweek( false ), hfullweek( false ),
446             hdow( false ), hyear( false ), hmonth( false ), hday( false ),
447             hzcount( false ), hdoy( false ), hzcount29( false ),
448             hhour( false ), hmin( false ), hsec( false ),
449             hsod( false ), hepoch( false ),
450             //hunixsec( false ), hunixusec( false ),
451             hbdsw( false ), hqzsw( false ), hgalw( false ), hirnw( false ),
452             hbdsfw( false ), hqzsfw( false ), hgalfw( false ), hirnfw( false ),
453             hbdse( false ), hqzse( false ), hgale( false ), hirne( false );
454 
455             // MJD, Julian Date, ANSI time, Unix time, Posix time, and
456             // 32-bit Zcounts are treated as stand-alone types and are
457             // not mixed with others if detected.
458 
459             // These variables will hold the values for use later.
460          double isow, isod, isec;
461          int iweek, ifullweek, idow, iyear, imonth, iday, izcount, idoy,
462             izcount29, ihour, imin, iepoch;
463          TimeSystem ts;
464 
465          for( TimeTag::IdToValue::iterator itr = info.begin();
466               itr != info.end(); itr++ )
467          {
468             switch( itr->first )
469             {
470                case 'P':
471                   ts = gpstk::StringUtils::asTimeSystem(itr->second);
472                   t.setTimeSystem(ts);
473                   break;
474 
475                case 'Q':
476                   t = MJD( asLongDouble(itr->second) );
477                   break;
478 
479                case 'J':
480                   t = JulianDate( asLongDouble(itr->second) );
481                   break;
482 
483                case 'C':
484                   t = GPSWeekZcount().setZcount32( asInt(itr->second) );
485                   break;
486 
487                case 'K':
488                   t = ANSITime( asInt(itr->second) );
489                   break;
490 
491                case 'U':
492                case 'u':
493                {
494                   UnixTime tt;
495                   tt.setFromInfo( info );
496                   t = tt.convertToCommonTime();
497                   break;
498                }
499                break;
500 
501                case 'N':
502                case 'W':
503                {
504                   PosixTime tt;
505                   tt.setFromInfo( info );
506                   t = tt.convertToCommonTime();
507                   break;
508                }
509                break;
510 
511                case 'z':
512                case 'Z':
513                   hzcount = true;
514                   izcount = asInt(itr->second);
515                   break;
516 
517                case 's':
518                   hsod = true;
519                   isod = asDouble(itr->second);
520                   break;
521 
522                case 'g':
523                   hsow = true;
524                   isow = asDouble(itr->second);
525                   break;
526 
527                case 'w':
528                   idow = asInt(itr->second);
529                   hdow = true;
530                   break;
531 
532                case 'G':
533                   hweek = true;
534                   iweek = asInt(itr->second);
535                   break;
536 
537                case 'F':
538                   hfullweek = true;
539                   ifullweek = asInt(itr->second);
540                   break;
541 
542                case 'j':
543                   hdoy = true;
544                   idoy = asInt(itr->second);
545                   break;
546 
547                case 'b':
548                   hmonth = true;
549                   imonth = CivilTime::monthAbbrev(itr->second);
550                   if (imonth < 1)
551                   {
552                         ///@todo use a more appropriate exception class
553                      Exception
554                         exc("Invalid month abbreviation: " + itr->second);
555                      GPSTK_THROW(exc);
556                   }
557                   break;
558 
559                case 'B':
560                   hmonth = true;
561                   imonth = CivilTime::monthLong(itr->second);
562                   if (imonth < 1)
563                   {
564                         ///@todo use a more appropriate exception class
565                      Exception
566                         exc("Invalid month name: " + itr->second);
567                      GPSTK_THROW(exc);
568                   }
569                   break;
570 
571                case 'Y':
572                   hyear = true;
573                   iyear = asInt(itr->second);
574                   break;
575 
576                case 'y':
577                   hyear = true;
578                      // match the POSIX strptime() function:
579                      /* Year within century. When a century is not
580                       * otherwise specified, values in the range 69-99
581                       * refer to years in the twentieth century (1969
582                       * to 1999 inclusive); values in the range 00-68
583                       * refer to years in the twenty-first century
584                       * (2000 to 2068 inclusive). */
585                   if( itr->second.length() > 2)
586                   {
587                         ///@todo use a more appropriate exception class
588                      Exception
589                         exc("Invalid format for %y: expected 2 digits");
590                      GPSTK_THROW(exc);
591                   }
592                   iyear = asInt( itr->second );
593                   if (iyear >= 69)
594                      iyear += 1900;
595                   else
596                      iyear += 2000;
597                   break;
598 
599                case 'a':
600                case 'A':
601                {
602                   hdow = true;
603                   string thisDay = firstWord( itr->second );
604                   lowerCase(thisDay);
605                   if (isLike(thisDay, "sun.*")) idow = 0;
606                   else if (isLike(thisDay, "mon.*")) idow = 1;
607                   else if (isLike(thisDay, "tue.*")) idow = 2;
608                   else if (isLike(thisDay, "wed.*")) idow = 3;
609                   else if (isLike(thisDay, "thu.*")) idow = 4;
610                   else if (isLike(thisDay, "fri.*")) idow = 5;
611                   else if (isLike(thisDay, "sat.*")) idow = 6;
612                }
613                break;
614 
615                case 'm':
616                   hmonth = true;
617                   imonth = asInt(itr->second);
618                   break;
619 
620                case 'd':
621                   hday = true;
622                   iday = asInt(itr->second);
623                   break;
624 
625                case 'H':
626                   hhour = true;
627                   ihour = asInt(itr->second);
628                   break;
629 
630                case 'M':
631                   hmin = true;
632                   imin = asInt(itr->second);
633                   break;
634 
635                case 'S':
636                   hsec = true;
637                   isec = asDouble(itr->second);
638                   break;
639 
640                case 'f':
641                   hsec = true;
642                   isec = asDouble(itr->second);
643                   break;
644 
645                case 'c':
646                   hzcount29 = true;
647                   izcount29 = asInt(itr->second);
648                   break;
649 
650                case 'E':
651                   hepoch = true;
652                   iepoch = asInt(itr->second);
653                   break;
654 
655                case 'R':
656                   hepoch = hbdse = true;
657                   iepoch = asInt(itr->second);
658                   break;
659 
660                case 'T':
661                   hepoch = hgale = true;
662                   iepoch = asInt(itr->second);
663                   break;
664 
665                case 'V':
666                   hepoch = hqzse = true;
667                   iepoch = asInt(itr->second);
668                   break;
669 
670                case 'X':
671                   hepoch = hirne = true;
672                   iepoch = asInt(itr->second);
673                   break;
674 
675                case 'D': hfullweek = hbdsfw = true; break;
676                case 'e': hweek = hbdsw = true; break;
677                case 'L': hfullweek = hgalfw = true; break;
678                case 'l': hweek = hgalw = true; break;
679                case 'I': hfullweek = hqzsfw = true; break;
680                case 'i': hweek = hqzsw = true; break;
681                case 'O': hfullweek = hirnfw = true; break;
682                case 'o': hweek = hirnw = true; break;
683 
684                default:
685                      // do nothing
686                   break;
687 
688             };
689          }
690 
691          bool hbds(hbdse || hbdsfw || hbdsw);
692          bool hgal(hgale || hgalfw || hgalw);
693          bool hqzs(hqzse || hqzsfw || hqzsw);
694          bool hirn(hirne || hirnfw || hirnw);
695 
696             // We'll copy this time to 't' after all of the processing.
697          CommonTime ct(t);
698          ct.setTimeSystem(t.getTimeSystem());
699 
700             // Go through all of the types in order of least precise to most
701             // precise.
702          if( hepoch )
703          {
704             WeekSecond *ptt;
705             if(hbds) ptt = new BDSWeekSecond(ct);
706             else if(hqzs) ptt = new QZSWeekSecond(ct);
707             else if(hgal) ptt = new GALWeekSecond(ct);
708             else if(hirn) ptt = new IRNWeekSecond(ct);
709             else ptt = new GPSWeekSecond(ct);
710             ptt->setEpoch( iepoch );
711             ct = ptt->convertToCommonTime();
712             delete ptt;
713          }
714 
715          if( hyear )
716          {
717             YDSTime tt(ct);
718             tt.year = iyear;
719             ct = tt.convertToCommonTime();
720          }
721 
722          if( hmonth )
723          {
724             CivilTime tt(ct);
725             tt.month = imonth;
726             ct = tt.convertToCommonTime();
727          }
728 
729          if( hfullweek )
730          {
731             WeekSecond *ptt;
732             if(hbds) ptt = new BDSWeekSecond();
733             else if(hqzs) ptt = new QZSWeekSecond();
734             else if(hgal) ptt = new GALWeekSecond();
735             else if(hirn) ptt = new IRNWeekSecond();
736             else ptt = new GPSWeekSecond();
737 
738             //When if( hfullweek ) is the first if entered in the list
739             //of if's the conversion of CommonTime to WeekSecond
740             //causes an InvalidParameter error. The following if-else
741             //is a workaround.
742 	    if (ct == CommonTime::BEGINNING_OF_TIME)
743             {
744               ptt->week = ifullweek;
745             }
746 	    else
747             {
748               ptt->convertFromCommonTime(ct);
749               ptt->week = ifullweek;
750             }
751 
752             ct = ptt->convertToCommonTime();
753             delete ptt;
754          }
755 
756          if( hweek )
757          {
758             WeekSecond *ptt;
759             if(hbds) ptt = new BDSWeekSecond(ct);
760             else if(hqzs) ptt = new QZSWeekSecond(ct);
761             else if(hgal) ptt = new GALWeekSecond(ct);
762             else if(hirn) ptt = new IRNWeekSecond(ct);
763             else ptt = new GPSWeekSecond(ct);
764             ptt->setModWeek(iweek);
765             ct = ptt->convertToCommonTime();
766             delete ptt;
767          }
768 
769          if( hdow )
770          {
771             WeekSecond *ptt;
772             if(hbds) ptt = new BDSWeekSecond(ct);
773             else if(hqzs) ptt = new QZSWeekSecond(ct);
774             else if(hgal) ptt = new GALWeekSecond(ct);
775             else if(hirn) ptt = new IRNWeekSecond(ct);
776             else ptt = new GPSWeekSecond(ct);
777             ptt->sow = static_cast<double>(idow) * SEC_PER_DAY;
778             ct = ptt->convertToCommonTime();
779             delete ptt;
780          }
781 
782          if( hday )
783          {
784             CivilTime tt(ct);
785             tt.day = iday;
786             ct = tt.convertToCommonTime();
787          }
788 
789          if( hdoy )
790          {
791             YDSTime tt(ct);
792             tt.doy = idoy;
793             ct = tt.convertToCommonTime();
794          }
795 
796          if( hzcount29 )
797          {
798             GPSWeekZcount tt(ct);
799             tt.setZcount29( izcount29 );
800             ct = tt.convertToCommonTime();
801          }
802 
803          if( hzcount )
804          {
805             GPSWeekZcount tt(ct);
806             tt.zcount = izcount;
807             ct = tt.convertToCommonTime();
808          }
809 
810          if( hhour )
811          {
812             CivilTime tt(ct);
813             tt.hour = ihour;
814             ct = tt.convertToCommonTime();
815          }
816 
817          if( hmin )
818          {
819             CivilTime tt(ct);
820             tt.minute = imin;
821             ct = tt.convertToCommonTime();
822          }
823 
824          if( hsow )
825          {
826             WeekSecond *ptt;
827             if(hbds) ptt = new BDSWeekSecond(ct);
828             else if(hqzs) ptt = new QZSWeekSecond(ct);
829             else if(hgal) ptt = new GALWeekSecond(ct);
830             else if(hirn) ptt = new IRNWeekSecond(ct);
831             else ptt =  new GPSWeekSecond(ct);
832             ptt->sow = isow;
833             ct = ptt->convertToCommonTime();
834             delete ptt;
835          }
836 
837          if( hsod )
838          {
839             YDSTime tt(ct);
840             tt.sod = isod;
841             ct = tt.convertToCommonTime();
842          }
843 
844          if( hsec )
845          {
846             CivilTime tt(ct);
847             tt.second = isec;
848             ct = tt.convertToCommonTime();
849          }
850          t = ct;
851       }
852       catch( gpstk::StringUtils::StringException& se )
853       {
854          GPSTK_RETHROW( se );
855       }
856    }
857 
858 } // namespace gpstk
859