00001 #pragma ident "$Id: Epoch.cpp 1163 2008-03-28 13:01:33Z snelsen $"
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
00047 #include <iostream>
00048 #include <iomanip>
00049 #include <string>
00050 #include <ctime>
00051
00052 #include "gpstkplatform.h"
00053 #include "Epoch.hpp"
00054
00055 #include "TimeConstants.hpp"
00056 #include "TimeString.hpp"
00057
00058 #include "JulianDate.hpp"
00059 #include "MJD.hpp"
00060 #include "YDSTime.hpp"
00061 #include "CivilTime.hpp"
00062 #include "GPSWeekZcount.hpp"
00063 #include "GPSWeekSecond.hpp"
00064
00065
00066 namespace gpstk
00067 {
00068 using namespace std;
00069 using namespace gpstk::StringUtils;
00070
00071
00072 const double Epoch::ONE_NSEC_TOLERANCE = 1e-9;
00073
00074 const double Epoch::ONE_USEC_TOLERANCE = 1e-6;
00075
00076 const double Epoch::ONE_MSEC_TOLERANCE = 1e-3;
00077
00078 const double Epoch::ONE_SEC_TOLERANCE = 1;
00079
00080 const double Epoch::ONE_MIN_TOLERANCE = 60;
00081
00082 const double Epoch::ONE_HOUR_TOLERANCE = 3600;
00083
00084
00085 #ifdef _WIN32
00086 double Epoch::EPOCH_TOLERANCE = ONE_USEC_TOLERANCE;
00087 #else
00088 double Epoch::EPOCH_TOLERANCE = ONE_NSEC_TOLERANCE;
00089 #endif
00090
00092 const Epoch BEGINNING_OF_TIME(CommonTime::BEGINNING_OF_TIME);
00094 const Epoch END_OF_TIME(CommonTime::END_OF_TIME);
00095
00096 std::string Epoch::PRINT_FORMAT("%02m/%02d/%04Y %02H:%02M:%02S");
00097
00098 Epoch& Epoch::setTolerance(double tol)
00099 throw()
00100 {
00101 tolerance = tol;
00102 return *this;
00103 }
00104
00105
00106 Epoch::Epoch(const TimeTag& tt)
00107 throw(Epoch::EpochException)
00108 : tolerance(EPOCH_TOLERANCE)
00109 {
00110 set(tt);
00111 }
00112
00113 Epoch::Epoch(const CommonTime& ct)
00114 throw()
00115 : tolerance(EPOCH_TOLERANCE),
00116 core(ct)
00117 {}
00118
00123 Epoch::Epoch(const TimeTag& tt,
00124 short year)
00125 throw(Epoch::EpochException)
00126 : tolerance(EPOCH_TOLERANCE)
00127 {
00128 set(tt, year);
00129 }
00130
00131
00132
00133
00134 Epoch::Epoch(const GPSZcount& z)
00135 throw()
00136 : tolerance(EPOCH_TOLERANCE)
00137 {
00138 set(z);
00139 }
00140
00141
00142 Epoch::Epoch(const Epoch& right)
00143 throw()
00144 : core(right.core),
00145 tolerance(right.tolerance)
00146 {}
00147
00148
00149 Epoch& Epoch::operator=(const Epoch& right)
00150 throw()
00151 {
00152 core = right.core;
00153 tolerance = right.tolerance;
00154 return *this;
00155 }
00156
00157
00158
00159
00160 double Epoch::operator-(const Epoch& right) const
00161 throw()
00162 {
00163 return core - right.core;
00164 }
00165
00166
00167
00168
00169 Epoch Epoch::operator+(double seconds) const
00170 throw(Epoch::EpochException)
00171 {
00172 return Epoch(*this).addSeconds(seconds);
00173 }
00174
00175
00176
00177
00178 Epoch Epoch::operator-(double seconds) const
00179 throw(Epoch::EpochException)
00180 {
00181 return Epoch(*this).addSeconds(-seconds);
00182 }
00183
00184
00185
00186 Epoch& Epoch::operator+=(double seconds)
00187 throw(Epoch::EpochException)
00188 {
00189 return addSeconds(seconds);
00190 }
00191
00192
00193
00194 Epoch& Epoch::operator-=(double seconds)
00195 throw(Epoch::EpochException)
00196 {
00197 return addSeconds(-seconds);
00198 }
00199
00200
00201
00202 Epoch& Epoch::addSeconds(double seconds)
00203 throw(Epoch::EpochException)
00204 {
00205 try
00206 {
00207 core.addSeconds(seconds);
00208 return *this;
00209 }
00210 catch( InvalidRequest& ir )
00211 {
00212 Epoch::EpochException ee(ir);
00213 GPSTK_THROW(ee);
00214 }
00215 }
00216
00217
00218
00219 Epoch& Epoch::addSeconds(long seconds)
00220 throw(Epoch::EpochException)
00221 {
00222 try
00223 {
00224 core.addSeconds(seconds);
00225 return *this ;
00226 }
00227 catch( InvalidRequest& ir )
00228 {
00229 Epoch::EpochException ee(ir);
00230 GPSTK_THROW(ee);
00231 }
00232 }
00233
00234
00235
00236 Epoch& Epoch::addMilliSeconds(long msec)
00237 throw(Epoch::EpochException)
00238 {
00239 try
00240 {
00241 core.addMilliseconds(msec);
00242 return *this;
00243 }
00244 catch( InvalidRequest& ir )
00245 {
00246 Epoch::EpochException ee(ir);
00247 GPSTK_THROW(ee);
00248 }
00249 }
00250
00251
00252
00253 Epoch& Epoch::addMicroSeconds(long usec)
00254 throw(Epoch::EpochException)
00255 {
00256 try
00257 {
00258 long ms = usec / 1000;
00259 usec -= ms * 1000;
00260 core.addMilliseconds(ms);
00261
00262 core.addSeconds(static_cast<double>(usec) * 1e-6);
00263 return *this;
00264 }
00265 catch( InvalidRequest& ir )
00266 {
00267 Epoch::EpochException ee(ir);
00268 GPSTK_THROW(ee);
00269 }
00270 }
00271
00272
00273 bool Epoch::operator==(const Epoch &right) const
00274 throw()
00275 {
00276
00277 return (ABS(operator-(right)) <=
00278 ((tolerance > right.tolerance) ? right.tolerance : tolerance));
00279 }
00280
00281
00282 bool Epoch::operator!=(const Epoch &right) const
00283 throw()
00284 {
00285 return !(operator==(right));
00286 }
00287
00288
00289 bool Epoch::operator<(const Epoch &right) const
00290 throw()
00291 {
00292 return (operator-(right) <
00293 -((tolerance > right.tolerance) ? right.tolerance : tolerance));
00294 }
00295
00296
00297 bool Epoch::operator>(const Epoch &right) const
00298 throw()
00299 {
00300 return (operator-(right) >
00301 ((tolerance > right.tolerance) ? right.tolerance : tolerance));
00302 }
00303
00304
00305 bool Epoch::operator<=(const Epoch &right) const
00306 throw()
00307 {
00308 return !(operator>(right));
00309 }
00310
00311
00312 bool Epoch::operator>=(const Epoch &right) const
00313 throw()
00314 {
00315 return !(operator<(right));
00316 }
00317
00318 template <class TimeTagType>
00319 TimeTagType Epoch::get() const
00320 throw(Epoch::EpochException)
00321 {
00322 try
00323 {
00324 return TimeTagType(core);
00325 }
00326 catch( Exception& e)
00327 {
00328 EpochException ee(e);
00329 GPSTK_THROW(ee);
00330 }
00331 }
00332
00336 long double Epoch::JD() const
00337 throw(Epoch::EpochException)
00338 {
00339 return get<JulianDate>().jd;
00340 }
00341
00345 long double Epoch::MJD() const
00346 throw(Epoch::EpochException)
00347 {
00348 return get<gpstk::MJD>().mjd;
00349 }
00350
00352 short Epoch::year() const
00353 throw(Epoch::EpochException)
00354 {
00355 return static_cast<short>(get<CivilTime>().year);
00356 }
00357
00359 short Epoch::month() const
00360 throw(Epoch::EpochException)
00361 {
00362 return static_cast<short>(get<CivilTime>().month);
00363 }
00364
00366 short Epoch::day() const
00367 throw(Epoch::EpochException)
00368 {
00369 return static_cast<short>(get<CivilTime>().day);
00370 }
00371
00373 short Epoch::dow() const
00374 throw(Epoch::EpochException)
00375 {
00376 return (((static_cast<long>(JD()) % 7) + 1) % 7) ;
00377 }
00378
00380 short Epoch::hour() const
00381 throw(Epoch::EpochException)
00382 {
00383 return static_cast<short>(get<CivilTime>().hour);
00384 }
00385
00387 short Epoch::minute() const
00388 throw(Epoch::EpochException)
00389 {
00390 return static_cast<short>(get<CivilTime>().minute);
00391 }
00392
00394 double Epoch::second() const
00395 throw(Epoch::EpochException)
00396 {
00397 return get<CivilTime>().second;
00398 }
00399
00401 double Epoch::sod() const
00402 throw(Epoch::EpochException)
00403 {
00404 return get<YDSTime>().sod;
00405 }
00406
00408 short Epoch::GPSweek10() const
00409 throw(Epoch::EpochException)
00410 {
00411 return static_cast<short>(get<GPSWeekSecond>().getWeek10());
00412 }
00413
00415 long Epoch::GPSzcount() const
00416 throw(Epoch::EpochException)
00417 {
00418 return get<GPSWeekZcount>().zcount;
00419 }
00420
00422 long Epoch::GPSzcountFloor() const
00423 throw(Epoch::EpochException)
00424 {
00425 Epoch e = *this + .75;
00426 return e.get<GPSWeekZcount>().zcount;
00427 }
00428
00434 unsigned long Epoch::GPSzcount32() const
00435 throw(Epoch::EpochException)
00436 {
00437 return get<GPSWeekZcount>().getZcount32();
00438 }
00439
00441 unsigned long Epoch::GPSzcount32Floor() const
00442 throw(Epoch::EpochException)
00443 {
00444 Epoch e = *this + .75;
00445 return e.get<GPSWeekZcount>().getZcount32();
00446 }
00447
00449 double Epoch::GPSsow() const
00450 throw(Epoch::EpochException)
00451 {
00452 return get<GPSWeekSecond>().sow;
00453 }
00454
00456 short Epoch::GPSweek() const
00457 throw(Epoch::EpochException)
00458 {
00459 return static_cast<short>(get<GPSWeekSecond>().week);
00460 }
00461
00463 short Epoch::doy() const
00464 throw(Epoch::EpochException)
00465 {
00466 return static_cast<short>(get<YDSTime>().doy);
00467 }
00468
00470 struct timeval Epoch::unixTime() const
00471 throw(Epoch::EpochException)
00472 {
00473 return get<UnixTime>().tv;
00474 }
00475
00476 Epoch::operator GPSZcount() const
00477 throw(Epoch::EpochException)
00478 {
00479 try
00480 {
00481
00482 Epoch e = *this + 0.75;
00483 GPSWeekZcount wz = get<GPSWeekZcount>();
00484 return GPSZcount(wz.week, wz.zcount);
00485 }
00486 catch (gpstk::InvalidParameter& ip)
00487 {
00488 Epoch::EpochException ee(ip);
00489 GPSTK_THROW(ee);
00490 }
00491 }
00492
00493 Epoch::operator CommonTime() const
00494 throw()
00495 {
00496 return core;
00497 }
00498
00499 Epoch& Epoch::set(const TimeTag& tt)
00500 throw(Epoch::EpochException)
00501 {
00502 try
00503 {
00504 core = tt;
00505 return *this;
00506 }
00507 catch(InvalidParameter& ip)
00508 {
00509 EpochException ee(ip);
00510 GPSTK_THROW(ee);
00511 }
00512 }
00513
00514 Epoch& Epoch::set(const TimeTag& tt,
00515 short year)
00516 throw(Epoch::EpochException)
00517 {
00518 try
00519 {
00520 GPSWeekSecond ws(tt);
00521 ws.setEpoch(whichGPSEpoch(ws.getWeek10(), year));
00522 core = ws;
00523 return *this;
00524 }
00525 catch(InvalidParameter& ip)
00526 {
00527 EpochException ee(ip);
00528 GPSTK_THROW(ee);
00529 }
00530 }
00531
00532 Epoch& Epoch::set(const CommonTime& c)
00533 throw()
00534 {
00535 core = c;
00536 return *this;
00537 }
00538
00539
00540
00541
00542
00543
00544
00545 Epoch& Epoch::set(const GPSZcount& z)
00546 throw(Epoch::EpochException)
00547 {
00548 try
00549 {
00550 GPSWeekZcount wz(core);
00551 wz.week = z.getWeek();
00552 wz.zcount = z.getZcount();
00553 core = wz;
00554 return *this ;
00555 }
00556 catch(Exception& exc)
00557 {
00558 EpochException ee(exc);
00559 GPSTK_THROW(ee);
00560 }
00561 }
00562
00563 Epoch& Epoch::setTime(const CommonTime& ct)
00564 throw(Epoch::EpochException)
00565 {
00566 try
00567 {
00568 long myDAY, mySOD, ctDAY, ctSOD;
00569 double myFSOD, ctFSOD;
00570 core.get(myDAY, mySOD, myFSOD);
00571 ct.get(ctDAY, ctSOD, ctFSOD);
00572 core.set(myDAY, ctSOD, ctFSOD);
00573 return *this;
00574 }
00575 catch(InvalidParameter& ip)
00576 {
00577 EpochException ee(ip);
00578 GPSTK_THROW(ee);
00579 }
00580 }
00581
00582 Epoch& Epoch::setDate(const CommonTime& ct)
00583 throw(Epoch::EpochException)
00584 {
00585 try
00586 {
00587 long myDAY, mySOD, ctDAY, ctSOD;
00588 double myFSOD, ctFSOD;
00589 core.get(myDAY, mySOD, myFSOD);
00590 ct.get(ctDAY, ctSOD, ctFSOD);
00591 core.set(ctDAY, mySOD, myFSOD);
00592 return *this;
00593 }
00594 catch(InvalidParameter& ip)
00595 {
00596 EpochException ee(ip);
00597 GPSTK_THROW(ee);
00598 }
00599 }
00600
00601
00602 Epoch& Epoch::setLocalTime()
00603 throw(Epoch::EpochException)
00604 {
00605 time_t t;
00606 time(&t);
00607 struct tm *ltod;
00608 ltod = localtime(&t);
00609 return set(CivilTime(1900 + ltod->tm_year,
00610 ltod->tm_mon + 1,
00611 ltod->tm_mday,
00612 ltod->tm_hour,
00613 ltod->tm_min,
00614 ltod->tm_sec));
00615 }
00616
00617 Epoch& Epoch::scanf(const string& str,
00618 const string& fmt)
00619 throw(StringException)
00620 {
00621 try
00622 {
00623 scanTime( core, str, fmt );
00624 return *this;
00625 }
00626 catch (StringException& se)
00627 {
00628 GPSTK_RETHROW(se);
00629 }
00630 }
00631
00632
00633 string Epoch::printf(const string& fmt) const
00634 throw(StringException)
00635 {
00636 try
00637 {
00638 return printTime( core, fmt );
00639 }
00640 catch (StringException& se)
00641 {
00642 GPSTK_RETHROW(se);
00643 }
00644 }
00645
00646 short Epoch::whichGPSEpoch(int week,
00647 int year) const
00648 throw(Epoch::EpochException)
00649 {
00650 try
00651 {
00652
00653 short epoch1 = GPSWeekSecond(CivilTime(year, 1, 1)).getEpoch();
00654
00655 short epoch2 = GPSWeekSecond(CivilTime(year, 12, 31)).getEpoch();
00656
00657 if (epoch1 == epoch2)
00658 {
00659
00660 return epoch1;
00661 }
00662
00663 if (week <= 512)
00664 {
00665
00666 return epoch2;
00667 }
00668
00669
00670
00671 return epoch1;
00672 }
00673 catch( InvalidParameter& ip )
00674 {
00675 EpochException ee(ip);
00676 GPSTK_THROW(ee);
00677 }
00678 }
00679
00680
00681
00682
00683
00684 ostream& operator<<( ostream& s,
00685 const Epoch& e )
00686 {
00687 s << e.printf();
00688 return s;
00689 }
00690
00691 }