00001 #pragma ident "$Id: DayTime.cpp 2960 2011-11-02 05:01:16Z yanweignss $"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00051 #include <iostream>
00052 #include <iomanip>
00053 #include <string>
00054 #include <ctime>
00055
00056 #include "gpstkplatform.h"
00057 #include "DayTime.hpp"
00058 #include "FormatUtils.hpp"
00059
00060 namespace gpstk
00061 {
00062 using namespace std;
00063 using namespace gpstk::StringUtils;
00064
00065
00066
00068 static const char *MonthNames[] = {
00069 "Error",
00070 "January","February", "March", "April",
00071 "May", "June","July", "August",
00072 "September", "October", "November", "December"
00073 };
00074
00076 static const char *MonthAbbrevNames[] = {
00077 "err", "Jan", "Feb", "Mar", "Apr", "May", "Jun","Jul",
00078 "Aug", "Sep", "Oct", "Nov", "Dec"
00079 };
00080
00082 static const char *DayOfWeekNames[] = {
00083 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
00084 "Friday", "Saturday"
00085 };
00086
00088 static const char *DayOfWeekAbbrevNames[] = {
00089 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
00090 };
00091
00092
00093
00094
00095
00096
00097 const long DayTime::FACTOR = 1000;
00098
00099
00100 const long DayTime::HALFWEEK = 302400;
00101
00102 const long DayTime::FULLWEEK = 604800;
00103
00104 const long DayTime::SEC_DAY = 86400;
00105
00106 const long DayTime::MS_PER_DAY = SEC_DAY*1000;
00107
00108
00109 const double DayTime::JD_TO_MJD = 2400000.5;
00110
00111 const long DayTime::MJD_JDAY = 2400001L;
00112
00113 const long DayTime::GPS_EPOCH_JDAY = 2444245L;
00114
00115 const long DayTime::GPS_EPOCH_MJD = 44244L;
00116
00117 const long DayTime::UNIX_MJD = 40587L;
00118
00119
00120 const double DayTime::ONE_NSEC_TOLERANCE = 1e-9;
00121
00122 const double DayTime::ONE_USEC_TOLERANCE = 1e-6;
00123
00124 const double DayTime::ONE_MSEC_TOLERANCE = 1e-3;
00125
00126 const double DayTime::ONE_SEC_TOLERANCE = 1;
00127
00128 const double DayTime::ONE_MIN_TOLERANCE = 60;
00129
00130 const double DayTime::ONE_HOUR_TOLERANCE = 3600;
00131
00132
00133 #ifdef _WIN32
00134 double DayTime::DAYTIME_TOLERANCE = ONE_USEC_TOLERANCE;
00135 #else
00136 double DayTime::DAYTIME_TOLERANCE = ONE_NSEC_TOLERANCE;
00137 #endif
00138
00139
00140 const long DayTime::BEGIN_LIMIT_JDAY=0;
00141
00142
00143 const long DayTime::END_LIMIT_JDAY=3442448;
00144
00145 const DayTime DayTime::BEGINNING_OF_TIME =
00146 DayTime(DayTime::BEGIN_LIMIT_JDAY, 0, 0.0, DayTime::DAYTIME_TOLERANCE);
00147
00148 const DayTime DayTime::END_OF_TIME =
00149 DayTime(DayTime::END_LIMIT_JDAY, 0, 0.0, DayTime::DAYTIME_TOLERANCE);
00150
00151
00152
00153 bool DayTime::DAYTIME_TEST_VALID = true;
00154
00155
00156
00157 DayTime& DayTime::setTolerance(const double tol)
00158 throw()
00159 {
00160 tolerance = tol;
00161 return *this;
00162 }
00163
00164
00165
00166
00167 DayTime::DayTime()
00168 throw(DayTime::DayTimeException)
00169 {
00170 init();
00171 setSystemTime();
00172 }
00173
00174
00175
00176
00177
00178 DayTime::DayTime(short GPSWeek,
00179 double GPSSecond,
00180 TimeFrame f)
00181 throw(DayTime::DayTimeException)
00182 {
00183 init();
00184 setGPSfullweek(GPSWeek, GPSSecond, f);
00185 }
00186
00187
00188
00189
00190
00191
00192 DayTime::DayTime(short GPSWeek,
00193 double GPSSecond,
00194 short ayear,
00195 TimeFrame f)
00196 throw(DayTime::DayTimeException)
00197 {
00198 init();
00199 setGPS(GPSWeek, GPSSecond, ayear, f);
00200 }
00201
00202
00203
00204
00205
00206
00207 DayTime::DayTime(short GPSWeek,
00208 long zcount,
00209 short ayear,
00210 TimeFrame f)
00211 throw(DayTime::DayTimeException)
00212 {
00213 init();
00214 setGPS(GPSWeek, zcount, ayear, f);
00215 }
00216
00217
00218
00219
00220
00221 DayTime::DayTime(unsigned long fullZcount,
00222 TimeFrame f)
00223 throw(DayTime::DayTimeException)
00224 {
00225 init();
00226 setGPS(fullZcount, f);
00227 }
00228
00229
00230
00231
00232 DayTime::DayTime(const GPSZcount& z,
00233 TimeFrame f)
00234 throw(DayTime::DayTimeException)
00235 {
00236 init();
00237 setGPSZcount(z, f);
00238 }
00239
00240
00241
00242
00243 DayTime::DayTime(const CommonTime& c,
00244 TimeFrame f)
00245 throw(DayTime::DayTimeException)
00246 {
00247 init();
00248 setCommonTime(c, f);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 DayTime::DayTime(short yy,
00260 short mm,
00261 short dd,
00262 short hh,
00263 short min,
00264 double sec,
00265 TimeFrame f)
00266 throw(DayTime::DayTimeException)
00267 {
00268 init();
00269 setYMDHMS(yy, mm, dd, hh, min, sec, f);
00270 }
00271
00272
00273
00274
00275 DayTime::DayTime(long double mjd,
00276 TimeFrame f)
00277 throw(DayTime::DayTimeException)
00278 {
00279 init();
00280 setMJD(mjd, f);
00281 }
00282
00283
00284
00285
00286 DayTime::DayTime(double mjd,
00287 TimeFrame f)
00288 throw(DayTime::DayTimeException)
00289 {
00290 init();
00291 setMJD((long double)(mjd), f);
00292 }
00293
00294
00295
00296
00297
00298
00299 DayTime::DayTime(short year,
00300 short doy,
00301 double sod,
00302 TimeFrame f)
00303 throw(DayTime::DayTimeException)
00304 {
00305 init();
00306 setYDoySod(year,doy,sod,f);
00307 }
00308
00309
00310
00311
00312 DayTime::DayTime(const struct timeval& t,
00313 TimeFrame f)
00314 throw(DayTime::DayTimeException)
00315 {
00316 init();
00317 setUnix(t,f);
00318 timeFrame = f;
00319 }
00320
00321
00322
00323
00324 DayTime::DayTime(const DayTime &right)
00325 throw(DayTime::DayTimeException)
00326 {
00327 init();
00328 *this = right;
00329 }
00330
00331
00332 DayTime& DayTime::operator=(const DayTime& right)
00333 throw()
00334 {
00335 jday = right.jday;
00336 mSod = right.mSod;
00337 mSec = right.mSec;
00338 timeFrame = right.timeFrame;
00339 tolerance = right.tolerance;
00340 return *this;
00341 }
00342
00343
00344
00345
00346
00347
00348 double DayTime::operator-(const DayTime& right) const
00349 throw()
00350 {
00351 return ( SEC_DAY * double(jday - right.jday)
00352 + (double(mSod - right.mSod) + mSec - right.mSec) / FACTOR );
00353 }
00354
00355
00356
00357
00358 DayTime DayTime::operator+(double seconds) const
00359 throw()
00360 {
00361 return DayTime(*this).addSeconds(seconds);
00362 }
00363
00364
00365
00366
00367 DayTime DayTime::operator-(double seconds) const
00368 throw()
00369 {
00370 return DayTime(*this).addSeconds(-seconds);
00371 }
00372
00373
00374
00375 DayTime& DayTime::operator+=(double seconds)
00376 throw(DayTime::DayTimeException)
00377 {
00378 addSeconds(seconds);
00379 return *this;
00380 }
00381
00382
00383
00384 DayTime& DayTime::operator-=(double seconds)
00385 throw(DayTime::DayTimeException)
00386 {
00387 addSeconds(-seconds);
00388 return *this;
00389 }
00390
00391
00392
00393 DayTime& DayTime::addSeconds(double seconds)
00394 throw(DayTime::DayTimeException)
00395 {
00396 addLongDeltaTime(0, 0, seconds * FACTOR);
00397 return *this;
00398 }
00399
00400
00401
00402 DayTime& DayTime::addSeconds(long seconds)
00403 throw(DayTime::DayTimeException)
00404 {
00405 long ldd, lds ;
00406 ldd = seconds / SEC_DAY ;
00407 seconds %= SEC_DAY ;
00408 lds = seconds * FACTOR ;
00409 addLongDeltaTime(ldd, lds, 0) ;
00410 return *this ;
00411 }
00412
00413
00414
00415 DayTime& DayTime::addMilliSeconds(long msec)
00416 throw(DayTime::DayTimeException)
00417 {
00418 long ldd, lds ;
00419 ldd = msec / MS_PER_DAY ;
00420 msec %= MS_PER_DAY ;
00421 lds = msec * FACTOR / 1000 ;
00422 addLongDeltaTime(ldd, lds, 0) ;
00423 return *this;
00424 }
00425
00426
00427
00428 DayTime& DayTime::addMicroSeconds(long usec)
00429 throw(DayTime::DayTimeException)
00430 {
00431
00432 long ldd, lds, mult = (1000000 / FACTOR);
00433 double ds;
00434 ldd = usec / (1000000ll * SEC_DAY);
00435 usec %= (1000000ll * SEC_DAY);
00436 lds = usec / mult;
00437 ds = double(usec % mult) / mult;
00438 addLongDeltaTime(ldd, lds, ds);
00439 return *this;
00440 }
00441
00442
00443
00444
00445 bool DayTime::operator==(const DayTime &right) const
00446 throw()
00447 {
00448
00449 return (ABS(operator-(right)) <=
00450 ((tolerance > right.tolerance) ? right.tolerance : tolerance));
00451 }
00452
00453 bool DayTime::operator!=(const DayTime &right) const
00454 throw()
00455 {
00456 return !(operator==(right));
00457 }
00458
00459 bool DayTime::operator<(const DayTime &right) const
00460 throw()
00461 {
00462 return (operator-(right) <
00463 -((tolerance > right.tolerance) ? right.tolerance : tolerance));
00464 }
00465
00466 bool DayTime::operator>(const DayTime &right) const
00467 throw()
00468 {
00469 return (operator-(right) >
00470 ((tolerance > right.tolerance) ? right.tolerance : tolerance));
00471 }
00472
00473 bool DayTime::operator<=(const DayTime &right) const
00474 throw()
00475 {
00476 return !(operator>(right));
00477 }
00478
00479 bool DayTime::operator>=(const DayTime &right) const
00480 throw()
00481 {
00482 return !(operator<(right));
00483 }
00484
00485
00486
00487 DayTime& DayTime::setAllButTimeFrame(const DayTime& right)
00488 throw(DayTime::DayTimeException)
00489 {
00490 TimeFrame t = timeFrame;
00491 *this = right;
00492 timeFrame = t;
00493 return *this;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502 double DayTime::JD() const throw()
00503 {
00504 return (double(jday) + secOfDay() / SEC_DAY - 0.5);
00505 }
00506
00507
00508 double DayTime::MJD() const
00509 throw()
00510 {
00511 return JD() - JD_TO_MJD ;
00512 }
00513
00514
00515 short DayTime::year() const
00516 throw()
00517 {
00518 int yy, mm, dd;
00519 convertJDtoCalendar(jday, yy, mm, dd);
00520 return yy;
00521 }
00522
00523
00524 short DayTime::month() const
00525 throw()
00526 {
00527 int yy, mm, dd;
00528 convertJDtoCalendar(jday, yy, mm, dd);
00529 return mm;
00530 }
00531
00532
00533 short DayTime::day() const
00534 throw()
00535 {
00536 int yy,mm,dd;
00537 convertJDtoCalendar(jday, yy, mm, dd);
00538 return dd;
00539 }
00540
00541
00542 short DayTime::dayOfWeek() const
00543 throw()
00544 {
00545 return (((jday % 7) + 1) % 7) ;
00546 }
00547
00548
00549 short DayTime::hour() const
00550 throw()
00551 {
00552 int hh, mm ;
00553 double sec ;
00554 convertSODtoTime(secOfDay(), hh, mm, sec);
00555 return hh;
00556 }
00557
00558
00559 short DayTime::minute() const
00560 throw()
00561 {
00562 int hh, mm ;
00563 double sec ;
00564 convertSODtoTime(secOfDay(), hh, mm, sec);
00565 return mm;
00566 }
00567
00568
00569 double DayTime::second() const
00570 throw()
00571 {
00572 int hh, mm ;
00573 double sec ;
00574 convertSODtoTime(secOfDay(), hh, mm, sec) ;
00575 return sec;
00576 }
00577
00578
00579 short DayTime::GPS10bitweek() const
00580 throw()
00581 {
00582 return (GPSfullweek() % 1024);
00583 }
00584
00585
00586 long DayTime::GPSzcount() const
00587 throw()
00588 {
00589 return (long)((GPSsow() / 1.5) + .5);
00590 }
00591
00592
00593 long DayTime::GPSzcountFloor() const
00594 throw()
00595 {
00596 return (long)(GPSsow() / 1.5);
00597 }
00598
00599
00600 double DayTime::GPSsow() const
00601 throw()
00602 {
00603 return double(GPSday() * SEC_DAY) + secOfDay() ;
00604 }
00605
00606
00607 short DayTime::GPSfullweek() const
00608 throw()
00609 {
00610 return short(double(jday - GPS_EPOCH_JDAY) / 7) ;
00611 }
00612
00613
00614 short DayTime::DOY() const
00615 throw()
00616 {
00617 int yy, mm, dd;
00618 convertJDtoCalendar(jday, yy, mm, dd);
00619 return (jday - convertCalendarToJD(yy, 1, 1) + 1) ;
00620 }
00621
00622
00623 long double DayTime::getMJDasLongDouble() const
00624 throw()
00625 {
00626 return ( (long double)(jday)
00627 + (long double)(secOfDay() / SEC_DAY - 0.5)
00628 - (long double)(JD_TO_MJD) );
00629 }
00630
00631
00632 struct timeval DayTime::unixTime() const
00633 throw(DayTime::DayTimeException)
00634 {
00635 struct timeval t;
00636
00637 t.tv_sec = mSod / FACTOR
00638 + long(jday - MJD_JDAY - UNIX_MJD) * SEC_DAY ;
00639
00640 t.tv_usec = (mSod % FACTOR) * (1000000 / FACTOR)
00641 + long(mSec * (1000000 / FACTOR) + 0.5) ;
00642
00643 if (t.tv_usec >= 1000000)
00644 {
00645 t.tv_usec -= 1000000;
00646 ++t.tv_sec;
00647 }
00648
00649 return t;
00650 }
00651
00652
00653
00654
00655 unsigned long DayTime::fullZcount() const
00656 throw()
00657 {
00658 return ((long(GPS10bitweek()) << 19) + GPSzcount()) ;
00659 }
00660
00661
00662 unsigned long DayTime::fullZcountFloor() const
00663 throw()
00664 {
00665 return ((long(GPS10bitweek()) << 19) + GPSzcountFloor()) ;
00666 }
00667
00668 DayTime::operator GPSZcount() const
00669 throw(DayTime::DayTimeException)
00670 {
00671 try
00672 {
00673
00674 if(GPSzcount() == GPSZcount::ZCOUNT_WEEK)
00675 {
00676 return GPSZcount(GPSfullweek() + 1, 0);
00677 }
00678 else
00679 {
00680 return GPSZcount(GPSfullweek(), GPSzcount());
00681 }
00682 }
00683 catch (gpstk::InvalidParameter& ip)
00684 {
00685 DayTime::DayTimeException de(ip);
00686 GPSTK_THROW(de);
00687 }
00688 }
00689
00690 DayTime::operator CommonTime() const
00691 throw(DayTime::DayTimeException)
00692 {
00693 try
00694 {
00695
00696 return CommonTime().setInternal(jday, mSod, mSec / FACTOR);
00697 }
00698 catch (gpstk::InvalidParameter& ip)
00699 {
00700 DayTime::DayTimeException de(ip);
00701 GPSTK_THROW(de);
00702 }
00703 }
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 DayTime& DayTime::setYMDHMS(short yy,
00718 short month,
00719 short day,
00720 short hour,
00721 short min,
00722 double sec,
00723 TimeFrame f)
00724 throw(DayTime::DayTimeException)
00725 {
00726 setYMD(yy, month, day, f);
00727 return setHMS(hour, min, sec, f);
00728 }
00729
00730
00731
00732
00733
00734
00735
00736 DayTime& DayTime::setGPS(short week,
00737 double sow,
00738 TimeFrame f)
00739 throw(DayTime::DayTimeException)
00740 {
00741 short fullweek=week;
00742 if(week < 1024) {
00743 DayTime ndt;
00744 ndt.setSystemTime();
00745 fullweek = 1024*(ndt.GPSfullweek()/1024) + week;
00746 }
00747 return setGPSfullweek(fullweek,sow,f);
00748 }
00749
00750
00751
00752
00753
00754
00755
00756 DayTime& DayTime::setGPS(short week,
00757 long zcount,
00758 TimeFrame f)
00759 throw(DayTime::DayTimeException)
00760 {
00761 return setGPS(week, double(zcount) * 1.5, f);
00762 }
00763
00764
00765
00766
00767
00768
00769
00770 DayTime& DayTime::setGPS(short week,
00771 long zcount,
00772 short year,
00773 TimeFrame f)
00774 throw(DayTime::DayTimeException)
00775 {
00776 return setGPS(week, double(zcount) * 1.5, year, f);
00777 }
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 DayTime& DayTime::setGPS(short week,
00788 double sow,
00789 short year,
00790 TimeFrame f)
00791 throw(DayTime::DayTimeException)
00792 {
00793 bool valid = true;
00794
00795 if (DAYTIME_TEST_VALID)
00796 {
00797 if ((year < 1980) || (week < 0))
00798 valid = false;
00799 }
00800
00801 if (valid)
00802 {
00803 DayTime dt;
00804
00805
00806 week %= 1024;
00807
00808 dt.setYMD(year, 1, 1);
00809
00810
00811 short z1 = dt.GPSfullweek() / 1024;
00812
00813 dt.setYMD(year, 12, 31);
00814
00815
00816 short z2 = dt.GPSfullweek() / 1024;
00817
00818
00819 if (z1 == z2)
00820 {
00821 return setGPSfullweek(week + z1 * 1024, sow, f);
00822 }
00823
00824 else
00825 {
00826 if (week <= 512)
00827 {
00828 return setGPSfullweek(week + z2 * 1024, sow, f);
00829 }
00830 else if (week > 512)
00831 {
00832 return setGPSfullweek(week + z1 * 1024, sow, f);
00833 }
00834 }
00835 }
00836
00837
00838 if(DAYTIME_TEST_VALID)
00839 {
00840 using gpstk::StringUtils::asString ;
00841 DayTimeException dte("Input inconsistent: year "
00842 + asString<int>(year)
00843 + " cannot contain 10-bit GPS week "
00844 + asString<short>(week));
00845 GPSTK_THROW(dte);
00846 }
00847
00848 return *this;
00849 }
00850
00851
00852
00853
00854
00855
00856
00857 DayTime& DayTime::setGPS(unsigned long Zcount,
00858 TimeFrame f)
00859 throw(DayTime::DayTimeException)
00860 {
00861 short cweek = (Zcount >> 19) & 0x3FF ;
00862 long zcount = Zcount & 0x7FFFFL ;
00863 if(DAYTIME_TEST_VALID)
00864 {
00865 if(cweek < 0 || cweek > 1023 ||
00866 zcount < 0 || zcount > 403199 )
00867 {
00868 using gpstk::StringUtils::asString ;
00869 DayTimeException dte("Invalid Full GPS Z-count: "
00870 + asString<unsigned long>(Zcount));
00871 GPSTK_THROW(dte);
00872 }
00873 }
00874 return setGPS(cweek, zcount, f);
00875 }
00876
00877
00878
00879
00880
00881
00882 DayTime& DayTime::setGPSfullweek(short fullweek,
00883 double sow,
00884 TimeFrame f)
00885 throw(DayTime::DayTimeException)
00886 {
00887 if(DAYTIME_TEST_VALID)
00888 {
00889 if(fullweek < 0 ||
00890 sow < 0.0 ||
00891 sow >= double(FULLWEEK))
00892 {
00893 using gpstk::StringUtils::asString ;
00894 DayTimeException dte("Invalid week/seconds-of-week: "
00895 + asString<short>(fullweek)+ "/"
00896 + asString(sow));
00897 GPSTK_THROW(dte);
00898 }
00899 }
00900 jday = GPS_EPOCH_JDAY + 7 * long(fullweek) + long(sow / SEC_DAY);
00901 double sod = sow - SEC_DAY * long(sow / SEC_DAY);
00902 return setSecOfDay(sod, f);
00903 }
00904
00905
00906
00907
00908
00909
00910
00911 DayTime& DayTime::setGPSZcount(const GPSZcount& z,
00912 TimeFrame f)
00913 throw(DayTime::DayTimeException)
00914 {
00915 setGPS(z.getWeek(), z.getZcount(), f) ;
00916 return *this ;
00917 }
00918
00919
00920
00921
00922
00923 DayTime& DayTime::setCommonTime(const CommonTime& c,
00924 TimeFrame f)
00925 throw()
00926 {
00927 c.get(jday, mSod, mSec);
00928
00929 mSec *= FACTOR;
00930 timeFrame = f;
00931 return *this;
00932 }
00933
00934
00935
00936
00937
00938
00939
00940 DayTime& DayTime::setYDoySod(short year,
00941 short doy,
00942 double sod,
00943 TimeFrame f)
00944 throw(DayTime::DayTimeException)
00945 {
00946 setYDoy(year, doy, f);
00947 return setSecOfDay(sod, f);
00948 }
00949
00950
00951
00952
00953
00954
00955 DayTime& DayTime::setMJD(long double mjd,
00956 TimeFrame f)
00957 throw(DayTime::DayTimeException)
00958 {
00959 if(DAYTIME_TEST_VALID)
00960 {
00961 if(mjd < (long double)(BEGIN_LIMIT_JDAY-MJD_JDAY) ||
00962 mjd > (long double)(END_LIMIT_JDAY-MJD_JDAY))
00963 {
00964 DayTimeException dte("Invalid MJD: "
00965 + gpstk::StringUtils::asString(mjd)) ;
00966 GPSTK_THROW(dte) ;
00967 }
00968 }
00969 jday = long(mjd + 1.0) ;
00970 long double sod = SEC_DAY * (mjd + 1.0 - double(jday)) ;
00971 jday += MJD_JDAY - 1 ;
00972 mSod = long(FACTOR * sod) ;
00973 mSec = FACTOR * double(sod) - double(mSod) ;
00974 realignInternals();
00975 timeFrame = f ;
00976 return *this ;
00977 }
00978
00979
00980 DayTime& DayTime::setUnix(const struct timeval& t,
00981 TimeFrame f)
00982 throw(DayTime::DayTimeException)
00983 {
00984 long sec = t.tv_sec ;
00985 double dt = double(sec) + (t.tv_usec * 1.e-6) ;
00986 jday = MJD_JDAY + UNIX_MJD + long(dt / SEC_DAY) ;
00987 sec -= long(dt / SEC_DAY) * SEC_DAY ;
00988 dt = double(sec) + (t.tv_usec * 1.e-6) ;
00989 return setSecOfDay(dt);
00990 }
00991
00992
00993 DayTime& DayTime::setANSI(const time_t& t,
00994 TimeFrame f)
00995 throw(DayTime::DayTimeException)
00996 {
00997 long double dt = (long double)(t);
00998 dt /= SEC_DAY;
00999 dt += UNIX_MJD;
01000 return setMJD(dt, f);
01001 }
01002
01003
01004 DayTime& DayTime::setSystemTime()
01005 throw(DayTime::DayTimeException)
01006 {
01007 #if defined(ANSI_ONLY)
01008 time_t t;
01009 time(&t);
01010 setANSI(t, LocalSystem);
01011 #elif defined(WIN32)
01012 _timeb t;
01013 _ftime(&t);
01014 timeval tv;
01015 tv.tv_sec = t.time;
01016 tv.tv_usec = t.millitm*1000;
01017 setUnix(tv, LocalSystem);
01018 #else
01019 timeval t;
01020 gettimeofday(&t, NULL);
01021 setUnix(t, LocalSystem);
01022 #endif
01023 return *this;
01024 }
01025
01026
01027 DayTime& DayTime::setLocalTime()
01028 throw(DayTime::DayTimeException)
01029 {
01030 time_t t;
01031 time(&t);
01032 struct tm *ltod;
01033 ltod = localtime(&t);
01034 setYMDHMS(1900 + ltod->tm_year, ltod->tm_mon + 1, ltod->tm_mday,
01035 ltod->tm_hour, ltod->tm_min, ltod->tm_sec);
01036 return *this;
01037 }
01038
01039
01040
01041
01042
01043 DayTime& DayTime::setYMD(int yy,
01044 int mm,
01045 int dd,
01046 TimeFrame f)
01047 throw(DayTime::DayTimeException)
01048 {
01049 long tempDay = convertCalendarToJD(yy, mm, dd);
01050 if(DAYTIME_TEST_VALID)
01051 {
01052 int y, m, d;
01053 convertJDtoCalendar(tempDay, y, m, d);
01054 if(y != yy || m != mm || d != dd)
01055 {
01056 using gpstk::StringUtils::asString ;
01057 DayTimeException dte("Invalid yy/mm/dd: " + asString<int>(yy) + "/"
01058 + asString<int>(mm) + "/" + asString<int>(dd)
01059 + " != " + asString<int>(y) + "/"
01060 + asString<int>(m) + "/" + asString<int>(d));
01061 GPSTK_THROW(dte);
01062 }
01063 }
01064 jday = tempDay;
01065 timeFrame = f;
01066 return *this;
01067 }
01068
01069
01070 DayTime& DayTime::setHMS(int hh,
01071 int mm,
01072 double sec,
01073 TimeFrame f)
01074 throw(DayTime::DayTimeException)
01075 {
01076 double sod = convertTimeToSOD(hh, mm, sec);
01077 if(DAYTIME_TEST_VALID)
01078 {
01079 int h, m;
01080 double s;
01081 convertSODtoTime(sod, h, m, s);
01082 if(h != hh || m != mm || ABS(s - sec) > tolerance)
01083 {
01084 using gpstk::StringUtils::asString ;
01085 DayTimeException dte("Invalid hh:mm:ss: " + asString<int>(hh)
01086 + ":" + asString<int>(mm)
01087 + ":" + asString(sec));
01088 GPSTK_THROW(dte);
01089 }
01090 }
01091 return setSecOfDay(sod,f);
01092 }
01093
01094
01095 DayTime& DayTime::setSecOfDay(double sod,
01096 TimeFrame f)
01097 throw(DayTime::DayTimeException)
01098 {
01099 if(DAYTIME_TEST_VALID)
01100 {
01101 if(sod < 0.0 || sod >= double(SEC_DAY))
01102 {
01103 DayTimeException dte("Invalid seconds-of-day: "
01104 + gpstk::StringUtils::asString(sod));
01105 GPSTK_THROW(dte);
01106 }
01107 }
01108 mSod = long(FACTOR * sod);
01109 mSec = FACTOR * sod - double(mSod);
01110 realignInternals();
01111 timeFrame = f;
01112 return *this;
01113 }
01114
01115
01116 DayTime& DayTime::setYDoy(int yy,
01117 int doy,
01118 TimeFrame f)
01119 throw(DayTime::DayTimeException)
01120 {
01121 jday = convertCalendarToJD(yy, 1, 1) + doy - 1;
01122 if(DAYTIME_TEST_VALID)
01123 {
01124 int y,m,d;
01125 convertJDtoCalendar(jday, y, m, d);
01126 if(y != yy)
01127 {
01128 DayTimeException dte("Invalid Year/Day-of-Year: "
01129 + gpstk::StringUtils::asString(yy)
01130 + "/" + gpstk::StringUtils::asString(doy));
01131 GPSTK_THROW(dte);
01132 }
01133 }
01134 timeFrame = f;
01135 return *this;
01136 }
01137
01138
01139
01140 DayTime& DayTime::setToString(const string& str,
01141 const string& fmt)
01142 throw(DayTime::DayTimeException, DayTime::FormatException,
01143 StringException)
01144 {
01145 try
01146 {
01147
01148 DayTime toReturn(*this);
01149
01150
01151 bool hmjd = false, hsow = false, hweek = false, hfullWeek = false,
01152 hdow = false, hyear = false, hmonth = false, hday= false,
01153 hzcount = false, hdoy = false, hfullzcount = false,
01154 hhour = false, hmin = false, hsec = false, hsod = false,
01155 hunixsec = false, hunixusec = false;
01156
01157 double imjd, isow;
01158 short iweek, ifullWeek, idow, imonth, iday;
01159 long izcount, idoy;
01160 long ifullzcount;
01161
01162 short iyear, ihour, imin;
01163 double isec, isod;
01164
01165
01166 long unixsec, unixusec;
01167
01168
01169 iyear = toReturn.year();
01170
01171 string f = fmt;
01172 string s = str;
01173
01174
01175
01176 while ( (s.size() > 0) && (f.size() > 0) )
01177 {
01178
01179
01180
01181 while ( (s.length() != 0) && (f.length() != 0) && (f[0] != '%') )
01182 {
01183
01184 s.erase(0,1);
01185 f.erase(0,1);
01186 }
01187
01188
01189 if ( (s.length() == 0) || (f.length() == 0) )
01190 break;
01191
01192
01193 f.erase(0,1);
01194
01195
01196 string::size_type fieldLength = string::npos;
01197
01198 if (!isalpha(f[0]))
01199 {
01200
01201
01202 fieldLength = asInt(f);
01203
01204
01205
01206 while ((!f.empty()) && (!isalpha(f[0])))
01207 f.erase(0,1);
01208 if (f.empty())
01209 break;
01210 }
01211 else
01212 {
01213
01214 char delimiter = 0;
01215 if (f.size() > 1)
01216 {
01217 if (f[1] != '%')
01218 {
01219 delimiter = f[1];
01220
01221 stripLeading(s);
01222 fieldLength = s.find(delimiter,0);
01223 }
01224
01225
01226
01227
01228 else if (fieldLength == string::npos)
01229 {
01230 fieldLength = 1;
01231 }
01232 }
01233 }
01234
01235
01236
01237 string toBeRemoved = s.substr(0, fieldLength);
01238
01239
01240 switch (f[0])
01241 {
01242 case 'Q':
01243 {
01244 imjd = asDouble(toBeRemoved);
01245 hmjd = true;
01246 }
01247 break;
01248
01249 case 'Z':
01250 {
01251 izcount = asInt(toBeRemoved);
01252 hzcount = true;
01253 }
01254 break;
01255
01256 case 's':
01257 {
01258 isod = asDouble(toBeRemoved);
01259 hsod = true;
01260 }
01261 break;
01262
01263 case 'g':
01264 {
01265 isow = asDouble(toBeRemoved);
01266 hsow = true;
01267 }
01268 break;
01269
01270 case 'w':
01271 {
01272 idow = asInt(toBeRemoved);
01273 hdow = true;
01274 }
01275 break;
01276
01277 case 'G':
01278 {
01279 iweek = asInt(toBeRemoved);
01280 hweek = true;
01281 }
01282 break;
01283
01284 case 'F':
01285 {
01286 ifullWeek = asInt(toBeRemoved);
01287 hfullWeek = true;
01288 }
01289 break;
01290
01291 case 'j':
01292 {
01293 idoy = asInt(toBeRemoved);
01294 hdoy = true;
01295 }
01296 break;
01297
01298 case 'b':
01299 case 'B':
01300 {
01301 string thisMonth(toBeRemoved);
01302 lowerCase(thisMonth);
01303
01304 if (isLike(thisMonth, "jan.*")) imonth = 1;
01305 else if (isLike(thisMonth, "feb.*")) imonth = 2;
01306 else if (isLike(thisMonth, "mar.*")) imonth = 3;
01307 else if (isLike(thisMonth, "apr.*")) imonth = 4;
01308 else if (isLike(thisMonth, "may.*")) imonth = 5;
01309 else if (isLike(thisMonth, "jun.*")) imonth = 6;
01310 else if (isLike(thisMonth, "jul.*")) imonth = 7;
01311 else if (isLike(thisMonth, "aug.*")) imonth = 8;
01312 else if (isLike(thisMonth, "sep.*")) imonth = 9;
01313 else if (isLike(thisMonth, "oct.*")) imonth = 10;
01314 else if (isLike(thisMonth, "nov.*")) imonth = 11;
01315 else if (isLike(thisMonth, "dec.*")) imonth = 12;
01316 else
01317 {
01318 FormatException fe("Invalid month entry for setToString");
01319 GPSTK_THROW(fe);
01320 }
01321 hmonth = true;
01322 }
01323 break;
01324
01325 case 'Y':
01326 {
01327 iyear = asInt(toBeRemoved);
01328 hyear = true;
01329 }
01330 break;
01331
01332 case 'y':
01333 {
01334 if (fieldLength == 2)
01335 {
01336 iyear = asInt(toBeRemoved) + 1900;
01337 if (iyear < 1980)
01338 iyear += 100;
01339 }
01340 else if (fieldLength == 3)
01341 {
01342 iyear = asInt(toBeRemoved) + 1000;
01343 if (iyear < 1980)
01344 iyear += 100;
01345 }
01346 else
01347 iyear = asInt(toBeRemoved);
01348
01349 hyear = true;
01350 }
01351 break;
01352
01353 case 'a':
01354 case 'A':
01355 {
01356 string thisDay = firstWord(toBeRemoved);
01357 lowerCase(thisDay);
01358 if (isLike(thisDay, "sun.*")) idow = 0;
01359 else if (isLike(thisDay, "mon.*")) idow = 1;
01360 else if (isLike(thisDay, "tue.*")) idow = 2;
01361 else if (isLike(thisDay, "wed.*")) idow = 3;
01362 else if (isLike(thisDay, "thu.*")) idow = 4;
01363 else if (isLike(thisDay, "fri.*")) idow = 5;
01364 else if (isLike(thisDay, "sat.*")) idow = 6;
01365 else
01366 {
01367 FormatException fe("Invalid day of week for setTostring");
01368 GPSTK_THROW(fe);
01369 }
01370 hdow = true;
01371 }
01372 break;
01373
01374 case 'm':
01375 {
01376 imonth = asInt(toBeRemoved);
01377 hmonth = true;
01378 }
01379 break;
01380
01381 case 'd':
01382 {
01383 iday = asInt(toBeRemoved);
01384 hday = true;
01385 }
01386 break;
01387
01388 case 'H':
01389 {
01390 ihour = asInt(toBeRemoved);
01391 hhour = true;
01392 }
01393 break;
01394
01395 case 'M':
01396 {
01397 imin = asInt(toBeRemoved);
01398 hmin = true;
01399 }
01400 break;
01401
01402 case 'S':
01403 {
01404 isec = asDouble(toBeRemoved);
01405 isec = double(short(isec));
01406 hsec = true;
01407 }
01408 break;
01409
01410 case 'f':
01411 {
01412 isec = asDouble(toBeRemoved);
01413 hsec = true;
01414 }
01415 break;
01416
01417 case 'U':
01418 {
01419 unixsec = asInt(toBeRemoved);
01420 hunixsec = true;
01421 }
01422 break;
01423
01424 case 'u':
01425 {
01426 unixusec = asInt(toBeRemoved);
01427 hunixusec = true;
01428 }
01429 break;
01430
01431 case 'C':
01432 {
01433 ifullzcount = asInt(toBeRemoved);
01434 hfullzcount = true;
01435 }
01436
01437 default:
01438 {
01439
01440 }
01441 break;
01442 }
01443
01444 stripLeading(s,toBeRemoved,1);
01445
01446
01447 f.erase(0,1);
01448 }
01449
01450 if ( s.length() != 0 )
01451 {
01452
01453 FormatException fe(
01454 "Processing error - parts of strings left unread - " + s);
01455 GPSTK_THROW(fe);
01456 }
01457
01458 if (f.length() != 0)
01459 {
01460
01461 FormatException fe(
01462 "Processing error - parts of strings left unread - " + f);
01463 GPSTK_THROW(fe);
01464 }
01465
01466 if (!hmjd && !hsow && !hweek && !hfullWeek && !hdow && !hmonth &&
01467 !hday&& !hzcount && !hdoy && !hfullzcount && !hhour && !hmin &&
01468 !hsec && !hsod && !hunixsec && !hunixusec)
01469 {
01470 FormatException fe("Incomplete time specification for setToString");
01471 GPSTK_THROW(fe);
01472 }
01473
01474
01475 if (hsow)
01476 toReturn.setGPSfullweek(0, isow);
01477 if (hdow && !hsow)
01478 toReturn.setGPSfullweek(0, idow * double(SEC_DAY));
01479 if (hzcount)
01480 toReturn.setGPSfullweek(0, izcount);
01481 if (hfullzcount)
01482 toReturn.setGPS(ifullzcount);
01483 if (hfullWeek)
01484 toReturn.setGPSfullweek(ifullWeek, toReturn.GPSsow());
01485 if (hweek)
01486 toReturn.setGPS(iweek, toReturn.GPSsow(), iyear);
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496 if (hyear || hmonth || hday || hhour || hmin || hsec )
01497 {
01498 int nyear = toReturn.year();
01499 int nmonth = toReturn.month();
01500 int nday = toReturn.day();
01501 int nhour = toReturn.hour();
01502 int nmin = toReturn.minute();
01503 double dsec = toReturn.second();
01504
01505 if (hyear) nyear = iyear;
01506 if (hmonth) nmonth = imonth;
01507 if (hday) nday = iday;
01508 if (hhour) nhour = ihour;
01509 if (hmin) nmin = imin;
01510 if (hmin) dsec = isec;
01511 toReturn.setYMDHMS(nyear, nmonth, nday,
01512 nhour, nmin, dsec);
01513 }
01514
01515
01516 if (hdoy)
01517 toReturn.setYDoySod(toReturn.year(), idoy, toReturn.DOYsecond());
01518 if (hsod)
01519 toReturn.setYDoySod(toReturn.year(), toReturn.DOY(), isod);
01520
01521
01522 if (hmjd)
01523 toReturn.setMJD(imjd);
01524
01525
01526 if (hunixsec || hunixusec)
01527 {
01528 struct timeval tv = toReturn.unixTime();
01529 if (hunixsec) tv.tv_sec = unixsec;
01530 if (hunixusec) tv.tv_usec = unixusec;
01531
01532 toReturn.setUnix(tv);
01533 }
01534
01535 *this = toReturn;
01536 return *this;
01537 }
01538 catch(gpstk::Exception& exc)
01539 {
01540 DayTime::DayTimeException dte(exc);
01541 dte.addText("Cannot generate time");
01542 GPSTK_THROW(dte);
01543 }
01544 catch(std::exception& exc)
01545 {
01546 DayTime::DayTimeException dte(exc.what());
01547 dte.addText("Cannot generate time");
01548 GPSTK_THROW(dte);
01549 }
01550 }
01551
01552
01553 string DayTime::printf(const char *fmt) const
01554 throw(gpstk::StringUtils::StringException)
01555 {
01556 string rv = fmt;
01557 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*S"),
01558 string("Sd"), (short)second());
01559 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*(\\.[[:digit:]]+)?f"),
01560 string("ff"), second());
01561 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*G"),
01562 string("Ghd"), GPS10bitweek());
01563 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*F"),
01564 string("Fhd"), GPSfullweek());
01565 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*(\\.[[:digit:]]+)?g"),
01566 string("gf"), GPSsow());
01567 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*(\\.[[:digit:]]+)?s"),
01568 string("sf"), DOYsecond());
01569 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*(\\.[[:digit:]]+)?Q"),
01570 string("QLf"), getMJDasLongDouble());
01571 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*Y"),
01572 string("Yhd"), year());
01573 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*y"),
01574 string("yhd"), (short)(year() % 100));
01575 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*m"),
01576 string("mhd"), month());
01577 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*b"),
01578 string("bs"), MonthAbbrevNames[month()]);
01579 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*B"),
01580 string("Bs"), MonthNames[month()]);
01581 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*d"),
01582 string("dhd"), day());
01583 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*H"),
01584 string("Hhd"), hour());
01585 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*M"),
01586 string("Mhd"), minute());
01587 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*w"),
01588 string("whd"), dayOfWeek());
01589 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*a"),
01590 string("as"), DayOfWeekAbbrevNames[dayOfWeek()]);
01591 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*A"),
01592 string("As"), DayOfWeekNames[dayOfWeek()]);
01593 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*z"),
01594 string("zd"), GPSzcountFloor());
01595 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*Z"),
01596 string("Zd"), GPSzcount());
01597 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*U"),
01598 string("Ud"), unixTime().tv_sec);
01599 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*u"),
01600 string("ud"), unixTime().tv_usec);
01601 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*j"),
01602 string("jhd"), DOY());
01603 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*C"),
01604 string("Cd"), fullZcount());
01605 rv = formattedPrint(rv, string("%[ 0-]?[[:digit:]]*c"),
01606 string("cd"), fullZcountFloor());
01607
01608 return rv;
01609 }
01610
01611 std::string DayTime::toString(int decimals,char datesep, char timesep) const
01612 throw(gpstk::StringUtils::StringException)
01613 {
01614 string fmt = FormatUtils::format("%%04Y%c%%02m%c%%02d %%02H%c%%02M%c%%0%2.0f",
01615 datesep,datesep,timesep,timesep);
01616 if(decimals>0)
01617 {
01618 fmt = FormatUtils::format("%%04Y%c%%02m%c%%02d %%02H%c%%02M%c%%0%d.%df",
01619 datesep,datesep,timesep,timesep,
01620 3+decimals,decimals);
01621 }
01622
01623 return printf(fmt);
01624 }
01625
01626
01627 std::string DayTime::asString() const
01628 throw(gpstk::StringUtils::StringException)
01629 {
01630 ostringstream o;
01631 o << *this;
01632 return o.str();
01633 }
01634
01635
01636 void DayTime::dump(std::ostream& s) const
01637 throw(DayTime::DayTimeException)
01638 {
01639
01640
01641
01642 s << " internal: jday " << jday << endl;
01643 s << " internal: mSod " << mSod << endl;
01644 s << " internal: mSec " << fixed << setprecision(15) << mSec << endl;
01645 s << " internal: tolerance " << fixed << setprecision(15) << tolerance << endl;
01646 s << " double JD(): " << fixed << setprecision(6) << JD() << endl;
01647 s << " double MJD(): " << fixed << setprecision(6) << MJD() << endl;
01648 s << " short year(): " << year() << endl;
01649 s << " short month(): " << month() << endl;
01650 s << " short day(): " << day() << endl;
01651 s << " short dayOfWeek(): " << dayOfWeek() << endl;
01652 int yy,mm,dd;
01653 getYMD(yy, mm, dd);
01654 s << " void getYMD(int& yy, int& mm, int& dd): " << yy << " " << mm
01655 << " " << dd << endl;
01656 s << " short hour(): " << hour() << endl;
01657 s << " short minute(): " << minute() << endl;
01658 s << " double second(): " << fixed << setprecision(6) << second()
01659 << endl;
01660 s << " double secOfDay(): " << fixed << setprecision(6) << secOfDay()
01661 << endl;
01662 s << " short GPS10bitweek(): " << GPS10bitweek() << endl;
01663 s << " long GPSzcount(): " << GPSzcount() << endl;
01664 s << " long GPSzcountFloor(): " << GPSzcountFloor() << endl;
01665 s << " double GPSsecond(): " << fixed << setprecision(6) << GPSsecond()
01666 << endl;
01667 s << " double GPSsow(): " << fixed << setprecision(6) << GPSsow()
01668 << endl;
01669 s << " short GPSday(): " << GPSday() << endl;
01670 s << " short GPSfullweek(): " << GPSfullweek() << endl;
01671 s << " short GPSyear(): " << GPSyear() << endl;
01672 s << " short DOYyear(): " << DOYyear() << endl;
01673 s << " short DOYday(): " << DOYday() << endl;
01674 s << " short DOY(): " << DOY() << endl;
01675 s << " double DOYsecond(): "<< fixed << setprecision(6) << DOYsecond()
01676 << endl;
01677 s << " double MJDdate(): " << fixed << setprecision(6) << MJDdate()
01678 << endl;
01679 s << " long double getMJDasLongDouble(): "
01680 << fixed << setprecision(6) << getMJDasLongDouble() << endl;
01681 struct timeval tv=unixTime();
01682 s << " struct timeval unixTime(): " << tv.tv_sec << " " << tv.tv_usec
01683 << endl;
01684 s << " unsigned long fullZcount(): " << fullZcount() << endl;
01685 s << " unsigned long fullZcountFloor(): " << fullZcountFloor() << endl;
01686 }
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696 void DayTime::convertJDtoCalendar(long jd,
01697 int& iyear,
01698 int& imonth,
01699 int& iday)
01700 throw()
01701 {
01702 long L, M, N, P, Q;
01703 if(jd > 2299160)
01704 {
01705 L = jd + 68569;
01706 M = (4 * L) / 146097;
01707 L = L - ((146097 * M + 3) / 4);
01708 N = (4000 * (L + 1)) / 1461001;
01709 L = L - ((1461 * N) / 4) + 31;
01710 P = (80 * L) / 2447;
01711 iday = int(L - (2447 * P) / 80);
01712 L = P / 11;
01713 imonth = int(P + 2 - 12 * L);
01714 iyear = int(100 * (M - 49) + N + L);
01715 }
01716 else
01717 {
01718 P = jd + 1402;
01719 Q = (P - 1) / 1461;
01720 L = P - 1461 * Q;
01721 M = (L - 1) / 365 - L / 1461;
01722 N = L - 365 * M + 30;
01723 P = (80 * N) / 2447;
01724 iday = int(N - (2447 * P) / 80);
01725 N = P / 11;
01726 imonth = int(P + 2 - 12 * N);
01727 iyear = int(4 * Q + M + N - 4716);
01728 if(iyear <= 0)
01729 {
01730 --iyear;
01731 }
01732 }
01733
01734 if(iyear > 1599 &&
01735 !(iyear % 100) &&
01736 (iyear % 400) &&
01737 imonth == 2 &&
01738 iday == 29)
01739 {
01740 imonth = 3;
01741 iday = 1;
01742 }
01743 }
01744
01745 long DayTime::convertCalendarToJD(int yy,
01746 int mm,
01747 int dd)
01748 throw()
01749 {
01750 if(yy == 0)
01751 --yy;
01752
01753 if(yy < 0)
01754 ++yy;
01755
01756 long jd;
01757 double y = double(yy), m = double(mm), d = double(dd);
01758
01759
01760
01761
01762
01763 if(yy < 1582 || (yy == 1582 && (mm < 10 || (mm == 10 && dd < 15))))
01764 {
01765 jd = 1729777 + dd + 367 * yy
01766 - long(7 * ( y + 5001 + long((m - 9) / 7)) / 4)
01767 + long(275 * m / 9);
01768 }
01769 else
01770 {
01771 jd = 1721029 + dd + 367 * yy
01772 - long(7 * (y + long((m + 9) / 12)) / 4)
01773 - long(3 * (long((y + (m - 9) / 7) / 100) + 1) / 4)
01774 + long(275 * m / 9);
01775
01776
01777 if( (! (yy % 100) &&
01778 (yy % 400) &&
01779 mm > 2 &&
01780 mm < 9) ||
01781 (!((yy - 1) % 100) &&
01782 ((yy - 1) % 400) &&
01783 mm == 1))
01784 {
01785 --jd;
01786 }
01787 }
01788 return jd;
01789 }
01790
01791 void DayTime::convertSODtoTime(double sod,
01792 int& hh,
01793 int& mm,
01794 double& sec)
01795 throw()
01796 {
01797
01798 if (sod < 0)
01799 {
01800 sod += (1 + (unsigned long)(sod / SEC_DAY)) * SEC_DAY ;
01801 }
01802 else if (sod >= SEC_DAY)
01803 {
01804 sod -= (unsigned long)(sod / SEC_DAY) * SEC_DAY ;
01805 }
01806
01807 double temp;
01808 sod = modf(sod, &temp);
01809 long seconds = long(temp);
01810
01811 hh = seconds / 3600 ;
01812 mm = (seconds % 3600) / 60 ;
01813 sec = double(seconds % 60) + sod ;
01814
01815 }
01816
01817 double DayTime::convertTimeToSOD(int hh,
01818 int mm,
01819 double sec)
01820 throw()
01821 {
01822 return (sec + 60. * (mm + 60. * hh));
01823 }
01824
01825
01826
01827 void DayTime::init()
01828 throw()
01829 {
01830 timeFrame = Unknown;
01831 tolerance = DAYTIME_TOLERANCE;
01832 jday = 0;
01833 mSod = 0;
01834 mSec = 0.0;
01835 }
01836
01837
01838 void DayTime::addLongDeltaTime(long ldd,
01839 long lds,
01840 double ds)
01841 throw(DayTime::DayTimeException)
01842 {
01843
01844
01845
01846 ldd += long(ds / MS_PER_DAY);
01847 ds -= long(ds / MS_PER_DAY) * double(MS_PER_DAY);
01848
01849
01850
01851
01852 long workingJday(jday), workingMsod(mSod) ;
01853 double workingMsec(mSec), temp(0) ;
01854
01855 workingMsec += ds ;
01856
01857 if (workingMsec < 0.)
01858 {
01859
01860
01861 workingMsec = 1 + modf(workingMsec, &temp);
01862
01863 if(workingMsec == 1) {
01864 workingMsec = 0;
01865 lds += long(temp);
01866 }
01867 else
01868 lds += long(temp) - 1;
01869 }
01870 else if (workingMsec >= 1.0)
01871 {
01872
01873 workingMsec = modf(workingMsec, &temp) ;
01874
01875 lds += long(temp) ;
01876 }
01877
01878 workingMsod += lds ;
01879
01880 ldd += workingMsod / (SEC_DAY * FACTOR) ;
01881
01882
01883
01884 workingMsod %= (SEC_DAY * FACTOR) ;
01885
01886
01887 if (workingMsod < 0)
01888 {
01889 workingMsod += (SEC_DAY * FACTOR) ;
01890 --ldd ;
01891 }
01892
01893 workingJday += ldd ;
01894
01895 if(workingJday < BEGIN_LIMIT_JDAY)
01896 {
01897 DayTime::DayTimeException dte("DayTime underflow") ;
01898 GPSTK_THROW(dte) ;
01899 }
01900 if(workingJday > END_LIMIT_JDAY)
01901 {
01902 DayTime::DayTimeException dte("DayTime overflow") ;
01903 GPSTK_THROW(dte) ;
01904 }
01905
01906
01907 jday = workingJday ;
01908 mSod = workingMsod ;
01909 mSec = workingMsec ;
01910
01911 realignInternals();
01912 }
01913
01914
01915
01916 void DayTime::realignInternals(void)
01917 throw()
01918 {
01919 if(fabs(mSec-1)/FACTOR < tolerance) {
01920
01921
01922 mSec = (mSec-1 < 0 ? 0 : mSec-1);
01923 mSod += 1;
01924 }
01925 if(mSod >= SEC_DAY*FACTOR) {
01926 mSod -= SEC_DAY*FACTOR;
01927 jday += 1;
01928 }
01929 }
01930
01931
01932
01933
01934
01935
01936
01937 ostream& operator<<( ostream& s,
01938 const DayTime& t )
01939 {
01940 s << t.printf("%02m/%02d/%04Y %02H:%02M:%02S");
01941 return s;
01942 }
01943
01944 }
01945