LSSTApplications  11.0-13-gbb96280,12.1.rc1,12.1.rc1+1,12.1.rc1+2,12.1.rc1+5,12.1.rc1+8,12.1.rc1-1-g06d7636+1,12.1.rc1-1-g253890b+5,12.1.rc1-1-g3d31b68+7,12.1.rc1-1-g3db6b75+1,12.1.rc1-1-g5c1385a+3,12.1.rc1-1-g83b2247,12.1.rc1-1-g90cb4cf+6,12.1.rc1-1-g91da24b+3,12.1.rc1-2-g3521f8a,12.1.rc1-2-g39433dd+4,12.1.rc1-2-g486411b+2,12.1.rc1-2-g4c2be76,12.1.rc1-2-gc9c0491,12.1.rc1-2-gda2cd4f+6,12.1.rc1-3-g3391c73+2,12.1.rc1-3-g8c1bd6c+1,12.1.rc1-3-gcf4b6cb+2,12.1.rc1-4-g057223e+1,12.1.rc1-4-g19ed13b+2,12.1.rc1-4-g30492a7
LSSTDataManagementBasePackage
DateTime.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
25 
26 
39 #include <limits>
40 #include <cmath>
41 
42 #include "lsst/daf/base/DateTime.h"
43 
44 #include "boost/format.hpp"
45 #include "boost/regex.hpp"
46 #include <vector>
47 
48 #include "lsst/pex/exceptions.h"
49 
50 namespace dafBase = lsst::daf::base;
51 namespace pexEx = lsst::pex::exceptions;
52 
53 // Epoch = 1970 JAN 1 00:00:00 = JD 2440587.5 = MJD 40587.0
54 static double const MJD_TO_JD = 2400000.5;
55 static double const EPOCH_IN_MJD = 40587.0;
56 static double const JD2000 = 2451544.50;
57 
59 static double const NSEC_PER_DAY = 86.4e12;
60 
62 static long long const LL_NSEC_PER_SEC = 1000000000LL;
63 // static long long const LL_NSEC_PER_DAY = 86400 * LL_NSEC_PER_SEC;
64 
65 // Maximum number of days expressible as signed 64-bit nanoseconds.
66 // 2^64 / 2 / 1e9 / 86400
67 // NOTE: long long nsecs will wrap:
68 // -- earliest date representable = sep 21, 1677 00:00:00
69 // -- latest date representable = apr 12, 2262 00:00:00
70 static double const MAX_DAYS = 106751.99;
71 
72 
73 #ifdef CAL_TO_JD
74 static double const HOURS_PER_DAY = 24.0;
75 static double const MIN_PER_DAY = 1440.0;
76 static double const SEC_PER_DAY = 86400.0;
77 #endif
78 
79 // Difference between Terrestrial Time and TAI.
80 static long long const TT_MINUS_TAI_NSECS = 32184000000LL;
81 
82 /* Leap second table as string.
83  *
84  * Source: http://maia.usno.navy.mil/ser7/tai-utc.dat
85  */
86 static std::string leapString =
87 "\
88 1961 JAN 1 =JD 2437300.5 TAI-UTC= 1.4228180 S + (MJD - 37300.) X 0.001296 S\n\
89 1961 AUG 1 =JD 2437512.5 TAI-UTC= 1.3728180 S + (MJD - 37300.) X 0.001296 S\n\
90 1962 JAN 1 =JD 2437665.5 TAI-UTC= 1.8458580 S + (MJD - 37665.) X 0.0011232S\n\
91 1963 NOV 1 =JD 2438334.5 TAI-UTC= 1.9458580 S + (MJD - 37665.) X 0.0011232S\n\
92 1964 JAN 1 =JD 2438395.5 TAI-UTC= 3.2401300 S + (MJD - 38761.) X 0.001296 S\n\
93 1964 APR 1 =JD 2438486.5 TAI-UTC= 3.3401300 S + (MJD - 38761.) X 0.001296 S\n\
94 1964 SEP 1 =JD 2438639.5 TAI-UTC= 3.4401300 S + (MJD - 38761.) X 0.001296 S\n\
95 1965 JAN 1 =JD 2438761.5 TAI-UTC= 3.5401300 S + (MJD - 38761.) X 0.001296 S\n\
96 1965 MAR 1 =JD 2438820.5 TAI-UTC= 3.6401300 S + (MJD - 38761.) X 0.001296 S\n\
97 1965 JUL 1 =JD 2438942.5 TAI-UTC= 3.7401300 S + (MJD - 38761.) X 0.001296 S\n\
98 1965 SEP 1 =JD 2439004.5 TAI-UTC= 3.8401300 S + (MJD - 38761.) X 0.001296 S\n\
99 1966 JAN 1 =JD 2439126.5 TAI-UTC= 4.3131700 S + (MJD - 39126.) X 0.002592 S\n\
100 1968 FEB 1 =JD 2439887.5 TAI-UTC= 4.2131700 S + (MJD - 39126.) X 0.002592 S\n\
101 1972 JAN 1 =JD 2441317.5 TAI-UTC= 10.0 S + (MJD - 41317.) X 0.0 S\n\
102 1972 JUL 1 =JD 2441499.5 TAI-UTC= 11.0 S + (MJD - 41317.) X 0.0 S\n\
103 1973 JAN 1 =JD 2441683.5 TAI-UTC= 12.0 S + (MJD - 41317.) X 0.0 S\n\
104 1974 JAN 1 =JD 2442048.5 TAI-UTC= 13.0 S + (MJD - 41317.) X 0.0 S\n\
105 1975 JAN 1 =JD 2442413.5 TAI-UTC= 14.0 S + (MJD - 41317.) X 0.0 S\n\
106 1976 JAN 1 =JD 2442778.5 TAI-UTC= 15.0 S + (MJD - 41317.) X 0.0 S\n\
107 1977 JAN 1 =JD 2443144.5 TAI-UTC= 16.0 S + (MJD - 41317.) X 0.0 S\n\
108 1978 JAN 1 =JD 2443509.5 TAI-UTC= 17.0 S + (MJD - 41317.) X 0.0 S\n\
109 1979 JAN 1 =JD 2443874.5 TAI-UTC= 18.0 S + (MJD - 41317.) X 0.0 S\n\
110 1980 JAN 1 =JD 2444239.5 TAI-UTC= 19.0 S + (MJD - 41317.) X 0.0 S\n\
111 1981 JUL 1 =JD 2444786.5 TAI-UTC= 20.0 S + (MJD - 41317.) X 0.0 S\n\
112 1982 JUL 1 =JD 2445151.5 TAI-UTC= 21.0 S + (MJD - 41317.) X 0.0 S\n\
113 1983 JUL 1 =JD 2445516.5 TAI-UTC= 22.0 S + (MJD - 41317.) X 0.0 S\n\
114 1985 JUL 1 =JD 2446247.5 TAI-UTC= 23.0 S + (MJD - 41317.) X 0.0 S\n\
115 1988 JAN 1 =JD 2447161.5 TAI-UTC= 24.0 S + (MJD - 41317.) X 0.0 S\n\
116 1990 JAN 1 =JD 2447892.5 TAI-UTC= 25.0 S + (MJD - 41317.) X 0.0 S\n\
117 1991 JAN 1 =JD 2448257.5 TAI-UTC= 26.0 S + (MJD - 41317.) X 0.0 S\n\
118 1992 JUL 1 =JD 2448804.5 TAI-UTC= 27.0 S + (MJD - 41317.) X 0.0 S\n\
119 1993 JUL 1 =JD 2449169.5 TAI-UTC= 28.0 S + (MJD - 41317.) X 0.0 S\n\
120 1994 JUL 1 =JD 2449534.5 TAI-UTC= 29.0 S + (MJD - 41317.) X 0.0 S\n\
121 1996 JAN 1 =JD 2450083.5 TAI-UTC= 30.0 S + (MJD - 41317.) X 0.0 S\n\
122 1997 JUL 1 =JD 2450630.5 TAI-UTC= 31.0 S + (MJD - 41317.) X 0.0 S\n\
123 1999 JAN 1 =JD 2451179.5 TAI-UTC= 32.0 S + (MJD - 41317.) X 0.0 S\n\
124 2006 JAN 1 =JD 2453736.5 TAI-UTC= 33.0 S + (MJD - 41317.) X 0.0 S\n\
125 2009 JAN 1 =JD 2454832.5 TAI-UTC= 34.0 S + (MJD - 41317.) X 0.0 S\n\
126 2012 JUL 1 =JD 2456109.5 TAI-UTC= 35.0 S + (MJD - 41317.) X 0.0 S\n\
127 2015 JUL 1 =JD 2457204.5 TAI-UTC= 36.0 S + (MJD - 41317.) X 0.0 S\n\
128 ";
129 
130 // Anonymous namespace for structures, classes, and formerly file-static
131 // functions.
132 namespace {
133 
135 struct Leap {
136  long long whenUtc;
137  long long whenTai;
138  double offset;
139  double mjdRef;
140  double drift;
141 };
142 
143 class LeapTable : public std::vector<Leap> {
144 public:
145  LeapTable(void);
146 };
147 
148 LeapTable leapSecTable;
149 
150 LeapTable::LeapTable(void) {
152 }
153 
158 template<typename NsType>
159 NsType utcToTai(NsType nsecs) {
160  size_t i;
161  for (i = 0; i < leapSecTable.size(); ++i) {
162  if (nsecs < leapSecTable[i].whenUtc) break;
163  }
164  if (i == 0) {
165  throw LSST_EXCEPT(
166  lsst::pex::exceptions::DomainError,
167  (boost::format(
168  "DateTime value too early for UTC-TAI conversion: %1%"
169  ) % nsecs).str());
170  }
171  Leap const& l(leapSecTable[i - 1]);
172  double mjd = static_cast<double>(nsecs) / NSEC_PER_DAY + EPOCH_IN_MJD;
173  double leapSecs = l.offset + (mjd - l.mjdRef) * l.drift;
174  NsType leapNSecs = static_cast<NsType>(leapSecs * 1.0e9 + 0.5);
175  return nsecs + leapNSecs;
176 }
177 
182 template<typename NsType>
183 NsType taiToUtc(NsType nsecs) {
184  size_t i;
185  for (i = 0; i < leapSecTable.size(); ++i) {
186  if (nsecs < leapSecTable[i].whenTai) break;
187  }
188  if (i == 0) {
189  throw LSST_EXCEPT(
190  lsst::pex::exceptions::DomainError,
191  (boost::format(
192  "DateTime value too early for TAI-UTC conversion: %1%"
193  ) % nsecs).str());
194  }
195  Leap const& l(leapSecTable[i - 1]);
196  double mjd = static_cast<double>(nsecs) / NSEC_PER_DAY + EPOCH_IN_MJD;
197  double leapSecs = l.offset + (mjd - l.mjdRef) * l.drift;
198  // Correct for TAI MJD vs. UTC MJD.
199  leapSecs /= 1.0 + l.drift * 1.0e9 / NSEC_PER_DAY;
200  NsType leapNSecs = static_cast<NsType>(leapSecs * 1.0e9 + 0.5);
201  return nsecs - leapNSecs;
202 }
203 
209 long long nsecAnyToTai(long long nsecs, dafBase::DateTime::Timescale scale) {
210  switch(scale) {
212  return nsecs;
214  return nsecs - TT_MINUS_TAI_NSECS;
216  return utcToTai(nsecs);
217  }
218  std::ostringstream os;
219  os << "Unsupported scale " << scale;
220  throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError, os.str());
221 }
222 
228 long long nsecTaiToAny(long long nsecs, dafBase::DateTime::Timescale scale) {
229  switch(scale) {
231  return nsecs;
233  return nsecs + TT_MINUS_TAI_NSECS;
235  return taiToUtc(nsecs);
236  }
237  std::ostringstream os;
238  os << "Unsupported scale " << scale;
239  throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError, os.str());
240 }
241 
242 
243 #ifdef CAL_TO_JD
244 
254 double calendarToJd(int year, int month, int day, int hour, int min, double sec) {
255  if ( month <= 2 ) {
256  year -= 1;
257  month += 12;
258  }
259  int a = int(year/100);
260  int b = 2 - a + int(a/4);
261 
262  int yy = 1582, mm = 10; //, d = 4;
263  if (year < yy || (year == yy && month < mm) || (year == yy && month == mm && day <= 4)) {
264  b = 0;
265  }
266 
267  double jd = static_cast<int>(365.25*(year + 4716)) +
268  static_cast<int>(30.6001*(month + 1)) + day + b - 1524.5;
269  jd += hour/HOURS_PER_DAY + min/MIN_PER_DAY + sec/SEC_PER_DAY;
270 
271  return jd;
272 }
273 
274 #endif // CAL_TO_JD
275 } // end anonymous namespace
276 
277 
285 
286  if (mjd > EPOCH_IN_MJD + MAX_DAYS) {
287  throw LSST_EXCEPT(
288  lsst::pex::exceptions::DomainError,
289  (boost::format("MJD too far in the future: %1%") % mjd).str());
290  }
291  if (mjd < EPOCH_IN_MJD - MAX_DAYS) {
292  throw LSST_EXCEPT(
293  lsst::pex::exceptions::DomainError,
294  (boost::format("MJD too far in the past: %1%") % mjd).str());
295  }
296  _nsecs = nsecAnyToTai(static_cast<long long>((mjd - EPOCH_IN_MJD) * NSEC_PER_DAY), scale);
297 }
298 
305  setNsecsFromMjd(jd - MJD_TO_JD, scale);
306 }
307 
314  setNsecsFromMjd(365.25*(epoch - 2000.0) + JD2000 - MJD_TO_JD, scale);
315 }
316 
317 
318 
323 dafBase::DateTime::DateTime(long long nsecs, Timescale scale) : _nsecs(nsecAnyToTai(nsecs, scale)) {
324 }
325 
331 dafBase::DateTime::DateTime(double date, DateSystem system, Timescale scale) {
332  switch (system) {
333  case MJD:
334  setNsecsFromMjd(date, scale);
335  break;
336  case JD:
337  setNsecsFromJd(date, scale);
338  break;
339  case EPOCH:
340  setNsecsFromEpoch(date, scale);
341  break;
342  default:
343  throw LSST_EXCEPT(pexEx::InvalidParameterError, "DateSystem must be MJD, JD, or EPOCH.");
344  break;
345  }
346 }
347 
348 
349 
359 dafBase::DateTime::DateTime(int year, int month, int day,
360  int hr, int min, int sec, Timescale scale) {
361 
362  int const minYear = 1902;
363  int const maxYear = 2261;
364  if ((year < minYear) || (year > maxYear)) {
365  throw LSST_EXCEPT(
366  lsst::pex::exceptions::DomainError,
367  (boost::format("Year = %d out of range [%04d, %04d]") % year % minYear % maxYear).str());
368  }
369 
370  struct tm tm;
371  tm.tm_year = year - 1900;
372  tm.tm_mon = month - 1;
373  tm.tm_mday = day;
374  tm.tm_hour = hr;
375  tm.tm_min = min;
376  tm.tm_sec = sec;
377  tm.tm_wday = 0;
378  tm.tm_yday = 0;
379  tm.tm_isdst = 0;
380  tm.tm_gmtoff = 0;
381 
382  // Convert to seconds since the epoch, correcting to UTC.
383  // Although timegm() is non-standard, it is a commonly-supported
384  // extension and is much safer/more reliable than mktime(3) in that
385  // it doesn't try to deal with the anomalies of local time zones.
386  time_t secs = timegm(&tm);
387 
388  // long long nsecs will blow out beyond 1677-09-21T00:00:00 and 2262-04-12T00:00:00
389  // (refering to the values of EPOCH_IN_MJD +/- MAX_DAYS ... exceeds 64 bits.)
390  // On older machines a tm struct is only 32 bits, and saturates at:
391  // low end - 1901-12-13, 20:45:52
392  // hi end - 2038-01-19, 03:14:07
393  // On newer machines the upper limit is a date in 2262, but the low end is unchanged,
394  // and a unit test will show the problem for dates later than 2038-01-19
395 
396  // timegm returns -1 on error, but the date at unix epoch -1 second also returns a valid value of -1,
397  // so be sure to test for that
398 
399  if (secs == -1) {
400  bool isBad = true; // assume the worst
401  if (year == 1969) {
402  // date may be the one date at which unix sec = -1; try a different year
403  tm.tm_year = 70;
404  if (timegm(&tm) != -1) {
405  isBad = false;
406  }
407  }
408  if (isBad) {
409  throw LSST_EXCEPT(
410  lsst::pex::exceptions::DomainError,
411  (boost::format("Unconvertible date: %04d-%02d-%02dT%02d:%02d:%02d")
412  % year % month % day % hr % min % sec).str());
413  }
414  }
415 
416  _nsecs = nsecAnyToTai(secs * LL_NSEC_PER_SEC, scale);
417 }
418 
426 dafBase::DateTime::DateTime(std::string const& iso8601, Timescale scale) {
427  boost::regex re;
428  if ((scale == TAI) || (scale == TT)) {
429  // no time zone character accepted
430  re = boost::regex("(\\d{4})-?(\\d{2})-?(\\d{2})" "T"
431  "(\\d{2}):?(\\d{2}):?(\\d{2})" "([.,](\\d*))?");
432  } else {
433  // time zone "Z" required
434  re = boost::regex("(\\d{4})-?(\\d{2})-?(\\d{2})" "T"
435  "(\\d{2}):?(\\d{2}):?(\\d{2})" "([.,](\\d*))?" "Z");
436  }
437  boost::smatch matches;
438  if (!regex_match(iso8601, matches, re)) {
439  throw LSST_EXCEPT(lsst::pex::exceptions::DomainError,
440  "Not in acceptable ISO8601 format: " + iso8601);
441  }
442  // determine TAI nsec truncated to integer seconds
443  // by constructing a DateTime from year, month, day...
444  DateTime dt(atoi(matches.str(1).c_str()), atoi(matches.str(2).c_str()),
445  atoi(matches.str(3).c_str()), atoi(matches.str(4).c_str()),
446  atoi(matches.str(5).c_str()), atoi(matches.str(6).c_str()),
447  scale);
448  _nsecs = dt._nsecs;
449  // add fractional seconds, if any
450  if (matches[7].matched) {
451  std::string frac = matches.str(8);
452  int places = frac.size();
453  if (places > 9) { // truncate fractional nanosec
454  frac.erase(9);
455  }
456  int value = atoi(frac.c_str());
457  while (places < 9) {
458  value *= 10;
459  ++places;
460  }
461  _nsecs += value;
462  }
463 }
464 
465 
474 double dafBase::DateTime::get(DateSystem system, Timescale scale) const {
475  switch (system) {
476  case MJD:
477  return _getMjd(scale);
478  break;
479  case JD:
480  return _getJd(scale);
481  break;
482  case EPOCH:
483  return _getEpoch(scale);
484  break;
485  default:
486  throw LSST_EXCEPT(pexEx::InvalidParameterError,
487  "DateSystem must be MJD, JD, or EPOCH.");
488  break;
489  }
490 }
491 
492 
496 long long dafBase::DateTime::nsecs(Timescale scale) const {
497  return nsecTaiToAny(_nsecs, scale);
498 }
499 
500 
506 
507  double nsecs = nsecTaiToAny(_nsecs, scale);
508  return nsecs / NSEC_PER_DAY + EPOCH_IN_MJD;
509 }
510 
511 
517  return _getMjd(scale) + MJD_TO_JD;
518 }
519 
525  return 2000.0 + (_getJd(scale) - JD2000)/365.25;
526 }
527 
528 
529 
530 
534 struct tm dafBase::DateTime::gmtime(Timescale scale) const {
535  struct tm gmt;
536  long long nsecs = nsecTaiToAny(_nsecs, scale);
537  // Round to negative infinity
538  long long frac = nsecs % LL_NSEC_PER_SEC;
539  if (nsecs < 0 && frac < 0) {
540  nsecs -= LL_NSEC_PER_SEC + frac;
541  }
542  else {
543  nsecs -= frac;
544  }
545  time_t secs = static_cast<time_t>(nsecs / LL_NSEC_PER_SEC);
546  gmtime_r(&secs, &gmt);
547  return gmt;
548 }
549 
553 struct timespec dafBase::DateTime::timespec(Timescale scale) const {
554  struct timespec ts;
555  long long nsecs = nsecTaiToAny(_nsecs, scale);
556  ts.tv_sec = static_cast<time_t>(nsecs / LL_NSEC_PER_SEC);
557  ts.tv_nsec = static_cast<int>(nsecs % LL_NSEC_PER_SEC);
558  return ts;
559 }
560 
564 struct timeval dafBase::DateTime::timeval(Timescale scale) const {
565  struct timeval tv;
566  long long nsecs = nsecTaiToAny(_nsecs, scale);
567  tv.tv_sec = static_cast<time_t>(nsecs / LL_NSEC_PER_SEC);
568  tv.tv_usec = static_cast<int>((nsecs % LL_NSEC_PER_SEC) / 1000);
569  return tv;
570 }
571 
575 std::string dafBase::DateTime::toString(Timescale scale) const {
576  struct tm gmt(this->gmtime(scale));
577 
578  long long fracnsecs = nsecTaiToAny(_nsecs, scale) % LL_NSEC_PER_SEC;
579  if (fracnsecs < 0) {
580  fracnsecs += LL_NSEC_PER_SEC;
581  }
582  auto fmtStr = scale == UTC ? "%04d-%02d-%02dT%02d:%02d:%02d.%09dZ"
583  : "%04d-%02d-%02dT%02d:%02d:%02d.%09d";
584  return (boost::format(fmtStr) %
585  (gmt.tm_year + 1900) % (gmt.tm_mon + 1) % gmt.tm_mday %
586  gmt.tm_hour % gmt.tm_min % gmt.tm_sec % fracnsecs).str();
587 }
588 
592 bool dafBase::DateTime::operator==(DateTime const& rhs) const {
593  return _nsecs == rhs._nsecs;
594 }
595 
602  struct timeval tv;
603  int ret = gettimeofday(&tv, 0);
604  if (ret != 0) {
605  throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError,
606  "Unable to get current time");
607  }
608  long long nsecs = tv.tv_sec * LL_NSEC_PER_SEC + tv.tv_usec * 1000LL;
609  return DateTime(nsecs, DateTime::UTC);
610 }
611 
615 void dafBase::DateTime::initializeLeapSeconds(std::string const& leapString) {
616  Leap l;
617  leapSecTable.clear();
618  boost::regex re("^\\d{4}.*?=JD\\s*([\\d.]+)\\s+TAI-UTC=\\s+([\\d.]+)\\s+S"
619  " \\+ \\(MJD - ([\\d.]+)\\) X ([\\d.]+)\\s*S$");
620  for (boost::cregex_iterator i = make_regex_iterator(leapString.c_str(), re);
621  i != boost::cregex_iterator(); ++i) {
622  double mjdUtc = strtod((*i)[1].first, 0) - MJD_TO_JD;
623  l.offset = strtod((*i)[2].first, 0);
624  l.mjdRef = strtod((*i)[3].first, 0);
625  l.drift = strtod((*i)[4].first, 0);
626  l.whenUtc = static_cast<long long>(
627  (mjdUtc - EPOCH_IN_MJD) * NSEC_PER_DAY);
628  l.whenTai = l.whenUtc + static_cast<long long>(
629  1.0e9 * (l.offset + (mjdUtc - l.mjdRef) * l.drift));
630  leapSecTable.push_back(l);
631  }
632 }
static DateTime now(void)
Definition: DateTime.cc:601
double _getEpoch(Timescale scale) const
Definition: DateTime.cc:524
void setNsecsFromEpoch(double epoch, Timescale scale)
a function to convert epoch to internal nsecs
Definition: DateTime.cc:313
Class for handling dates/times, including MJD, UTC, and TAI.
Definition: DateTime.h:58
double _getJd(Timescale scale) const
Definition: DateTime.cc:516
bool operator==(DateTime const &rhs) const
Definition: DateTime.cc:592
void setNsecsFromJd(double jd, Timescale scale)
a function to convert JD to internal nsecs
Definition: DateTime.cc:304
void setNsecsFromMjd(double mjd, Timescale scale)
a function to convert MJD to integral nsecs
Definition: DateTime.cc:284
static void initializeLeapSeconds(std::string const &leapString)
Definition: DateTime.cc:615
double get(DateSystem system=MJD, Timescale scale=TAI) const
Definition: DateTime.cc:474
long long nsecs(Timescale scale=TAI) const
Definition: DateTime.cc:496
struct tm gmtime(Timescale time) const
Definition: DateTime.cc:534
struct timeval timeval(Timescale time) const
Definition: DateTime.cc:564
long long _nsecs
Nanoseconds since Unix epoch.
Definition: DateTime.h:83
Interface for DateTime class.
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
double _getMjd(Timescale scale) const
Definition: DateTime.cc:505
afw::table::Key< double > b
Include files required for standard LSST Exception handling.
DateTime(long long nsecs=0LL, Timescale scale=TAI)
Definition: DateTime.cc:323
struct timespec timespec(Timescale time) const
Definition: DateTime.cc:553
std::string toString(Timescale scale) const
Definition: DateTime.cc:575