UTCDateTime.cc
Go to the documentation of this file.
1 #include <sstream>
2 #include <time.h>
3 #include <boost/format.hpp>
4 #include <utl/AugerException.h>
5 #include <utl/UTCDateTime.h>
6 #include <utl/LeapSeconds.h>
7 #include <utl/ErrorLogger.h>
8 
9 using namespace std;
10 using namespace boost;
11 using namespace utl;
12 
13 
14 UTCDateTime::UTCDateTime(const TimeStamp& ts)
15 {
16  time_t unixSecond;
17  const bool leap =
18  LeapSeconds::GetInstance().ConvertGPSToUnix(ts.GetGPSSecond(), unixSecond);
19  if (leap)
20  --unixSecond;
21  const tm* const gm = gmtime(&unixSecond);
22  UTCDate::Set(gm->tm_year + 1900, gm->tm_mon + 1, gm->tm_mday);
23  fHour = gm->tm_hour,
24  fMinute = gm->tm_min,
25  fSecond = (leap ? 60 : gm->tm_sec);
26  fNanosecond = ts.GetGPSNanoSecond();
27 }
28 
29 
30 void
31 UTCDateTime::SetHMS(const int hour, const int minute, const int second,
32  const double nanosecond)
33 {
34  if (hour < 0 || hour > 23) {
35  ostringstream err;
36  err << "UTCDateTime: hour " << hour << " not in range 0-23";
37  throw OutOfBoundException(err.str());
38  }
39  if (minute < 0 || minute > 59) {
40  ostringstream err;
41  err << "UTCDateTime: minute " << minute << " not in range 0-59";
42  throw OutOfBoundException(err.str());
43  }
44  if (second < 0 || second > 60) { // allow leap second
45  ostringstream err;
46  err << "UTCDateTime: second " << second << " not in range 0-59(60)";
47  throw OutOfBoundException(err.str());
48  }
49  if (nanosecond < 0 || nanosecond >= 1000000000) {
50  ostringstream err;
51  err << "UTCDateTime: nanosecond " << nanosecond << " not in range 0-1000000000";
52  throw OutOfBoundException(err.str());
53  }
54  fHour = hour;
55  fMinute = minute;
56  fSecond = second;
57  fNanosecond = nanosecond;
58  if (second != 60)
59  return;
60  time_t unixSecond = GetUnixSecond();
61  unsigned long gpsSecond;
62  LeapSeconds::GetInstance().ConvertUnixToGPS(unixSecond, gpsSecond);
63  --gpsSecond;
64  const bool isLeap =
65  LeapSeconds::GetInstance().ConvertGPSToUnix(gpsSecond, unixSecond);
66  if (!isLeap) {
67  LeapSeconds::GetInstance().Dump();
68  ostringstream err;
69  err << "UTCDateTime " << (*this) << " unix=" << unixSecond << " gps=" << gpsSecond << ": "
70  "Second is 60 but time does not correspond to a leap second" << endl;
71  ERROR(err);
72  throw OutOfBoundException(err.str());
73  }
74 }
75 
76 
77 string
78 UTCDateTime::GetInAugerFormat()
79  const
80 {
81  return
82  (format("%|1$02|:%|2$02|:%|3$02| %|4$02| %5% %|6$4|")
83  % fHour
84  % fMinute
85  % fSecond
86  % GetDay()
87  % fgMonthNames[GetMonth() - eJan]
88  % GetYear()
89  ).str();
90 }
91 
92 
93 string
94 UTCDateTime::GetInXMLFormat()
95  const
96 {
97  if (fNanosecond)
98  return (format("%1%T%|2$02|:%|3$02|:%|4$02|.%|5$09|Z")
99  % UTCDate::GetInXMLFormatZone("") % fHour % fMinute % fSecond % long(fNanosecond)).str();
100  else
101  return (format("%1%T%|2$02|:%|3$02|:%|4$02|Z")
102  % UTCDate::GetInXMLFormatZone("") % fHour % fMinute % fSecond).str();
103 }
104 
105 
106 string
107 UTCDateTime::GetInMySQLFormat()
108  const
109 {
110  return (format("%1% %|2$02|:%|3$02|:%|4$02|")
111  % UTCDate::GetInXMLFormatZone("") % fHour % fMinute % fSecond).str();
112 }
113 
114 TimeStamp
115 UTCDateTime::GetTimeStamp()
116  const
117 {
118  const time_t unixSecond = GetUnixSecond();
119  unsigned long gpsSecond;
120  LeapSeconds::GetInstance().ConvertUnixToGPS(unixSecond, gpsSecond);
121  if (fSecond == 60)
122  --gpsSecond;
123  return TimeStamp(gpsSecond, fNanosecond);
124 }
125 
126 
127 istream&
128 UTCDateTime::Parse(istream& is)
129 {
130  UTCDate::Parse(is, /*parse zone*/false);
131  char t = '?';
132  int hour = 0;
133  char colon = '?';
134  int minute = 0;
135  char colon2 = '?';
136  double second = 0;
137  char zone = '?';
138  if ((is >> t >> hour >> colon >> minute >> colon2 >> second) &&
139  t == 'T' && colon == ':' && colon2 == ':' &&
140  (!(is >> zone) || zone == 'Z')) {
141  const int sec = int(second);
142  const long nanosecond = long(1000000000*(second - sec) + 0.5);
143  SetHMS(hour, minute, sec, nanosecond);
144  is.clear();
145  return is;
146  }
147  ostringstream err;
148  err << "Initializing UTCDateTime variable failed: "
149  "t=" << t << " hour=" << hour << " colon=" << colon << " minute=" << minute
150  << " colon2=" << colon2 << " second=" << second << " zone=" << zone;
151  throw OutOfBoundException(err.str());
152 }
153 
154 
156 UTCDateTime::Max()
157 {
158  return UTCDateTime(TimeStamp::Max());
159 }
bool is(const double a, const double b)
Definition: testlib.cc:113
A TimeStamp holds GPS second and nanosecond for some event.
Definition: TimeStamp.h:110
Exception for reporting variable out of valid range.
constexpr double nanosecond
Definition: AugerUnits.h:143
const double second
Definition: GalacticUnits.h:32
constexpr double minute
Definition: AugerUnits.h:149
constexpr double hour
Definition: AugerUnits.h:150
unsigned long GetGPSSecond() const
GPS second.
Definition: TimeStamp.h:124
double GetGPSNanoSecond() const
GPS nanosecond.
Definition: TimeStamp.h:127
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165

, generated on Tue Sep 26 2023.