LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
LSSTDataManagementBasePackage
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
lsst::daf::base::DateTime Class Reference

Class for handling dates/times, including MJD, UTC, and TAI. More...

#include <DateTime.h>

Public Types

enum  Timescale { TAI, UTC, TT }
 
enum  DateSystem { JD, MJD, EPOCH }
 

Public Member Functions

 DateTime (long long nsecs=0LL, Timescale scale=TAI)
 
 DateTime (double date, DateSystem system=MJD, Timescale scale=TAI)
 
 DateTime (int year, int month, int day, int hr, int min, int sec, Timescale scale=TAI)
 
 DateTime (std::string const &iso8601)
 
long long nsecs (Timescale scale=TAI) const
 
double get (DateSystem system=MJD, Timescale scale=TAI) const
 
std::string toString (void) const
 
struct tm gmtime (void) const
 
struct timespec timespec (void) const
 
struct timeval timeval (void) const
 
bool operator== (DateTime const &rhs) const
 

Static Public Member Functions

static DateTime now (void)
 
static void initializeLeapSeconds (std::string const &leapString)
 

Private Member Functions

double _getMjd (Timescale scale) const
 
double _getJd (Timescale scale) const
 
double _getEpoch (Timescale scale) const
 
void setNsecsFromMjd (double mjd, Timescale scale)
 a function to convert MJD to interal nsecs More...
 
void setNsecsFromJd (double jd, Timescale scale)
 a function to convert JD to internal nsecs More...
 
void setNsecsFromEpoch (double epoch, Timescale scale)
 a function to convert epoch to internal nsecs More...
 
template<class Archive >
void serialize (Archive ar, int const version)
 

Private Attributes

long long _nsecs
 Nanoseconds since Unix epoch. More...
 

Friends

class boost::serialization::access
 

Detailed Description

Class for handling dates/times, including MJD, UTC, and TAI.

Definition at line 58 of file DateTime.h.

Member Enumeration Documentation

Enumerator
JD 
MJD 
EPOCH 

Definition at line 61 of file DateTime.h.

Enumerator
TAI 
UTC 
TT 

Definition at line 60 of file DateTime.h.

Constructor & Destructor Documentation

lsst::daf::base::DateTime::DateTime ( long long  nsecs = 0LL,
Timescale  scale = TAI 
)
explicit

Constructor.

Parameters
[in]nsecsNumber of nanoseconds since the epoch.
[in]scaleTimescale of input (TAI or UTC, default TAI).

Definition at line 291 of file DateTime.cc.

291  : _nsecs(nsecs) {
292  if (scale == UTC) {
293  _nsecs = utcToTai(_nsecs);
294  } else if (scale == TT) {
295  _nsecs -= TT_MINUS_TAI_NSECS;
296  }
297 }
long long nsecs(Timescale scale=TAI) const
Definition: DateTime.cc:441
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
lsst::daf::base::DateTime::DateTime ( double  date,
DateSystem  system = MJD,
Timescale  scale = TAI 
)
explicit

Constructor.

Parameters
[in]dateDate.
[in]systemThe requested date system (JD, MJD, or Julian epoch)
[in]scaleTimescale of input (TAI or UTC, default TAI).

Definition at line 304 of file DateTime.cc.

304  {
305  switch (system) {
306  case MJD:
307  setNsecsFromMjd(date, scale);
308  break;
309  case JD:
310  setNsecsFromJd(date, scale);
311  break;
312  case EPOCH:
313  setNsecsFromEpoch(date, scale);
314  break;
315  default:
316  throw LSST_EXCEPT(pexEx::InvalidParameterError, "DateSystem must be MJD, JD, or EPOCH.");
317  break;
318  }
319 }
void setNsecsFromEpoch(double epoch, Timescale scale)
a function to convert epoch to internal nsecs
Definition: DateTime.cc:281
void setNsecsFromJd(double jd, Timescale scale)
a function to convert JD to internal nsecs
Definition: DateTime.cc:272
void setNsecsFromMjd(double mjd, Timescale scale)
a function to convert MJD to interal nsecs
Definition: DateTime.cc:246
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
lsst::daf::base::DateTime::DateTime ( int  year,
int  month,
int  day,
int  hr,
int  min,
int  sec,
Timescale  scale = TAI 
)

Constructor.

Parameters
[in]yearYear number.
[in]monthMonth number (Jan = 1).
[in]dayDay number (1 to 31).
[in]hrHour number (0 to 23).
[in]minMinute number (0 to 59).
[in]secSecond number (0 to 60).
[in]scaleTimescale of input (TAI or UTC, default TAI).

Definition at line 332 of file DateTime.cc.

333  {
334 
335 
336  struct tm tm;
337  tm.tm_year = year - 1900;
338  tm.tm_mon = month - 1;
339  tm.tm_mday = day;
340  tm.tm_hour = hr;
341  tm.tm_min = min;
342  tm.tm_sec = sec;
343  tm.tm_wday = 0;
344  tm.tm_yday = 0;
345  tm.tm_isdst = 0;
346  tm.tm_gmtoff = 0;
347 
348  // Convert to seconds since the epoch, correcting to UTC.
349  // Although timegm() is non-standard, it is a commonly-supported
350  // extension and is much safer/more reliable than mktime(3) in that
351  // it doesn't try to deal with the anomalies of local time zones.
352  time_t secs = timegm(&tm);
353 
354  // long long nsecs will blow out beyond sep 21, 1677 0:00:00, and apr 12 2262 00:00:00
355  // (refering to the values of EPOCH_IN_MJD +/- MAX_DAYS ... exceeds 64 bits.)
356  // However, a tm struct is only 32 bits, and saturates at:
357  // low end - Dec 13 1901, 20:45:52
358  // hi end - Jan 19 2038, 03:14:07
359 
360  if (secs == -1) {
361  throw LSST_EXCEPT(
362  lsst::pex::exceptions::DomainError,
363  (boost::format("Unconvertible date: %04d-%02d-%02dT%02d:%02d:%02d")
364  % year % month % day % hr % min % sec).str());
365  }
366 
367  _nsecs = secs * LL_NSEC_PER_SEC;
368  if (scale == UTC) {
369  _nsecs = utcToTai(_nsecs);
370  } else if (scale == TT) {
371  _nsecs -= TT_MINUS_TAI_NSECS;
372  }
373 
374 }
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
lsst::daf::base::DateTime::DateTime ( std::string const &  iso8601)
explicit

Constructor. Accepts a restricted subset of ISO8601: yyyy-mm-ddThh:mm:ss.nnnnnnnnnZ where the - and : separators are optional, the fractional seconds are also optional, and the decimal point may be a comma.

Parameters
[in]iso8601ISO8601 representation of date and time. Must be UTC.

Definition at line 382 of file DateTime.cc.

382  {
383  boost::regex re("(\\d{4})-?(\\d{2})-?(\\d{2})" "T"
384  "(\\d{2}):?(\\d{2}):?(\\d{2})" "([.,](\\d*))?" "Z");
385  boost::smatch matches;
386  if (!regex_match(iso8601, matches, re)) {
387  throw LSST_EXCEPT(lsst::pex::exceptions::DomainError,
388  "Not in acceptable ISO8601 format: " + iso8601);
389  }
390  DateTime dt(atoi(matches.str(1).c_str()), atoi(matches.str(2).c_str()),
391  atoi(matches.str(3).c_str()), atoi(matches.str(4).c_str()),
392  atoi(matches.str(5).c_str()), atoi(matches.str(6).c_str()),
393  UTC);
394  _nsecs = dt._nsecs;
395  if (matches[7].matched) {
396  std::string frac = matches.str(8);
397  int places = frac.size();
398  if (places > 9) { // truncate fractional nanosec
399  frac.erase(9);
400  }
401  int value = atoi(frac.c_str());
402  while (places < 9) {
403  value *= 10;
404  ++places;
405  }
406  _nsecs += value;
407  }
408 }
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
DateTime(long long nsecs=0LL, Timescale scale=TAI)
Definition: DateTime.cc:291

Member Function Documentation

double lsst::daf::base::DateTime::_getEpoch ( Timescale  scale) const
private

Convert to Julian Epoch.

Parameters
[in]scaleDesired timescale (TAI or UTC, default TAI).
Returns
The Julian Epoch corresponding to the time.

Definition at line 482 of file DateTime.cc.

482  {
483  return 2000.0 + (_getJd(scale) - JD2000)/365.25;
484 }
double _getJd(Timescale scale) const
Definition: DateTime.cc:474
double lsst::daf::base::DateTime::_getJd ( Timescale  scale) const
private

Convert to Julian Day.

Parameters
[in]scaleDesired timescale (TAI or UTC, default TAI).
Returns
The Julian Day corresponding to the time.

Definition at line 474 of file DateTime.cc.

474  {
475  return _getMjd(scale) + MJD_TO_JD;
476 }
double _getMjd(Timescale scale) const
Definition: DateTime.cc:456
double lsst::daf::base::DateTime::_getMjd ( Timescale  scale) const
private

Convert to Modified Julian Day.

Parameters
[in]scaleDesired timescale (TAI or UTC, default TAI).
Returns
The Modified Julian Day corresponding to the time.

Definition at line 456 of file DateTime.cc.

456  {
457 
458  double nsecs;
459  if (scale == TAI) {
460  nsecs = static_cast<double>(_nsecs);
461  } else if (scale == TT) {
462  nsecs = static_cast<double>(_nsecs) + TT_MINUS_TAI_NSECS;
463  } else {
464  nsecs = static_cast<double>(taiToUtc(_nsecs));
465  }
466  return nsecs / NSEC_PER_DAY + EPOCH_IN_MJD;
467 }
long long nsecs(Timescale scale=TAI) const
Definition: DateTime.cc:441
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
double lsst::daf::base::DateTime::get ( DateSystem  system = MJD,
Timescale  scale = TAI 
) const

Generic Accessor

Returns
the date in the required system, for the requested scale
Parameters
[in]systemThe type of date requested (JD, MJD, or EPOCH)
[in]scaleThe time scale (UTC, or TAI)
Note
The NSECS can't be requested here as they're in long long form. A factory could be constructed, but it's more trouble than it's worth at this point.

Definition at line 419 of file DateTime.cc.

419  {
420  switch (system) {
421  case MJD:
422  return _getMjd(scale);
423  break;
424  case JD:
425  return _getJd(scale);
426  break;
427  case EPOCH:
428  return _getEpoch(scale);
429  break;
430  default:
431  throw LSST_EXCEPT(pexEx::InvalidParameterError,
432  "DateSystem must be MJD, JD, or EPOCH.");
433  break;
434  }
435 }
double _getEpoch(Timescale scale) const
Definition: DateTime.cc:482
double _getJd(Timescale scale) const
Definition: DateTime.cc:474
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
double _getMjd(Timescale scale) const
Definition: DateTime.cc:456
struct tm lsst::daf::base::DateTime::gmtime ( void  ) const

Convert to struct tm. Truncate fractional seconds.

Returns
Structure with decoded time in UTC.

Definition at line 492 of file DateTime.cc.

492  {
493  struct tm gmt;
494  long long nsecs = taiToUtc(_nsecs);
495  // Round to negative infinity
496  long long frac = nsecs % LL_NSEC_PER_SEC;
497  if (nsecs < 0 && frac < 0) {
498  nsecs -= LL_NSEC_PER_SEC + frac;
499  }
500  else {
501  nsecs -= frac;
502  }
503  time_t secs = static_cast<time_t>(nsecs / LL_NSEC_PER_SEC);
504  gmtime_r(&secs, &gmt);
505  return gmt;
506 }
long long nsecs(Timescale scale=TAI) const
Definition: DateTime.cc:441
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
void lsst::daf::base::DateTime::initializeLeapSeconds ( std::string const &  leapString)
static

Initialize leap second table.

Parameters
leapStringLeap second table from USNO as a single multiline string.

Definition at line 568 of file DateTime.cc.

568  {
569  Leap l;
570  leapSecTable.clear();
571  boost::regex re("^\\d{4}.*?=JD\\s*([\\d.]+)\\s+TAI-UTC=\\s+([\\d.]+)\\s+S"
572  " \\+ \\(MJD - ([\\d.]+)\\) X ([\\d.]+)\\s*S$");
573  for (boost::cregex_iterator i = make_regex_iterator(leapString.c_str(), re);
574  i != boost::cregex_iterator(); ++i) {
575  double mjdUtc = strtod((*i)[1].first, 0) - MJD_TO_JD;
576  l.offset = strtod((*i)[2].first, 0);
577  l.mjdRef = strtod((*i)[3].first, 0);
578  l.drift = strtod((*i)[4].first, 0);
579  l.whenUtc = static_cast<long long>(
580  (mjdUtc - EPOCH_IN_MJD) * NSEC_PER_DAY);
581  l.whenTai = l.whenUtc + static_cast<long long>(
582  1.0e9 * (l.offset + (mjdUtc - l.mjdRef) * l.drift));
583  leapSecTable.push_back(l);
584  }
585 }
dafBase::DateTime lsst::daf::base::DateTime::now ( void  )
static

Return current time as a DateTime.

Returns
DateTime representing the current time.

Definition at line 554 of file DateTime.cc.

554  {
555  struct timeval tv;
556  int ret = gettimeofday(&tv, 0);
557  if (ret != 0) {
558  throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
559  "Unable to get current time");
560  }
561  long long nsecs = tv.tv_sec * LL_NSEC_PER_SEC + tv.tv_usec * 1000LL;
562  return DateTime(nsecs, DateTime::UTC);
563 }
long long nsecs(Timescale scale=TAI) const
Definition: DateTime.cc:441
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
DateTime(long long nsecs=0LL, Timescale scale=TAI)
Definition: DateTime.cc:291
struct timeval timeval(void) const
Definition: DateTime.cc:522
long long lsst::daf::base::DateTime::nsecs ( Timescale  scale = TAI) const

Accessor.

Returns
Number of nanoseconds since the epoch in UTC or TAI.

Definition at line 441 of file DateTime.cc.

441  {
442  if (scale == TAI) {
443  return _nsecs;
444  } else if (scale == TT) {
445  return _nsecs + TT_MINUS_TAI_NSECS;
446  } else {
447  return taiToUtc(_nsecs);
448  }
449 }
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
bool lsst::daf::base::DateTime::operator== ( DateTime const &  rhs) const

Equality operator.

Returns
True if both DateTimes have the same nanosecond representation.

Definition at line 547 of file DateTime.cc.

547  {
548  return _nsecs == rhs._nsecs;
549 }
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
template<class Archive >
void lsst::daf::base::DateTime::serialize ( Archive  ar,
int const  version 
)
inlineprivate

Serialize DateTime to/from a Boost archive.

Parameters
[in,out]arArchive to access.
[in]versionVersion of class serializer.

Definition at line 98 of file DateTime.h.

98  {
99  ar & _nsecs;
100  }
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
void lsst::daf::base::DateTime::setNsecsFromEpoch ( double  epoch,
Timescale  scale 
)
private

a function to convert epoch to internal nsecs

Parameters
[in]epochThe Julian epoch
[in]scaleThe time scale (TAI, or UTC)

Definition at line 281 of file DateTime.cc.

281  {
282  setNsecsFromMjd(365.25*(epoch - 2000.0) + JD2000 - MJD_TO_JD, scale);
283 }
void setNsecsFromMjd(double mjd, Timescale scale)
a function to convert MJD to interal nsecs
Definition: DateTime.cc:246
void lsst::daf::base::DateTime::setNsecsFromJd ( double  jd,
Timescale  scale 
)
private

a function to convert JD to internal nsecs

Parameters
[in]jdThe Julian Day
[in]scaleThe time scale (TAI, or UTC)

Definition at line 272 of file DateTime.cc.

272  {
273  setNsecsFromMjd(jd - MJD_TO_JD, scale);
274 }
void setNsecsFromMjd(double mjd, Timescale scale)
a function to convert MJD to interal nsecs
Definition: DateTime.cc:246
void lsst::daf::base::DateTime::setNsecsFromMjd ( double  mjd,
Timescale  scale 
)
private

a function to convert MJD to interal nsecs

Parameters
[in]mjdThe Modified Julian Day
[in]scaleThe time scale (TAI, or UTC)

Definition at line 246 of file DateTime.cc.

246  {
247 
248  if (mjd > EPOCH_IN_MJD + MAX_DAYS) {
249  throw LSST_EXCEPT(
250  lsst::pex::exceptions::DomainError,
251  (boost::format("MJD too far in the future: %1%") % mjd).str());
252  }
253  if (mjd < EPOCH_IN_MJD - MAX_DAYS) {
254  throw LSST_EXCEPT(
255  lsst::pex::exceptions::DomainError,
256  (boost::format("MJD too far in the past: %1%") % mjd).str());
257  }
258  _nsecs = static_cast<long long>((mjd - EPOCH_IN_MJD) * NSEC_PER_DAY);
259  if (scale == UTC) {
260  _nsecs = utcToTai(_nsecs);
261  } else if (scale == TT) {
262  _nsecs -= TT_MINUS_TAI_NSECS;
263  }
264 
265 }
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
struct timespec lsst::daf::base::DateTime::timespec ( void  ) const

Convert to struct timespec.

Returns
Structure with UTC time in seconds and nanoseconds.

Definition at line 511 of file DateTime.cc.

511  {
512  struct timespec ts;
513  long long nsecs = taiToUtc(_nsecs);
514  ts.tv_sec = static_cast<time_t>(nsecs / LL_NSEC_PER_SEC);
515  ts.tv_nsec = static_cast<int>(nsecs % LL_NSEC_PER_SEC);
516  return ts;
517 }
long long nsecs(Timescale scale=TAI) const
Definition: DateTime.cc:441
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
struct timespec timespec(void) const
Definition: DateTime.cc:511
struct timeval lsst::daf::base::DateTime::timeval ( void  ) const

Convert time to struct timeval.

Returns
Structure with UTC time in seconds and microseconds.

Definition at line 522 of file DateTime.cc.

522  {
523  struct timeval tv;
524  long long nsecs = taiToUtc(_nsecs);
525  tv.tv_sec = static_cast<time_t>(nsecs / LL_NSEC_PER_SEC);
526  tv.tv_usec = static_cast<int>((nsecs % LL_NSEC_PER_SEC) / 1000);
527  return tv;
528 }
long long nsecs(Timescale scale=TAI) const
Definition: DateTime.cc:441
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
struct timeval timeval(void) const
Definition: DateTime.cc:522
std::string lsst::daf::base::DateTime::toString ( void  ) const

Accessor.

Returns
ISO8601-formatted string representation. Always UTC.

Definition at line 533 of file DateTime.cc.

533  {
534  struct tm gmt(this->gmtime());
535  long long nsecs = taiToUtc(_nsecs) % LL_NSEC_PER_SEC;
536  if (nsecs < 0) {
537  nsecs += LL_NSEC_PER_SEC;
538  }
539  return (boost::format("%04d-%02d-%02dT%02d:%02d:%02d.%09dZ") %
540  (gmt.tm_year + 1900) % (gmt.tm_mon + 1) % gmt.tm_mday %
541  gmt.tm_hour % gmt.tm_min % gmt.tm_sec % nsecs).str();
542 }
long long nsecs(Timescale scale=TAI) const
Definition: DateTime.cc:441
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
struct tm gmtime(void) const
Definition: DateTime.cc:492

Friends And Related Function Documentation

friend class boost::serialization::access
friend

Definition at line 93 of file DateTime.h.

Member Data Documentation

long long lsst::daf::base::DateTime::_nsecs
private

Nanoseconds since Unix epoch.

Definition at line 83 of file DateTime.h.


The documentation for this class was generated from the following files: