libutil++  1.9.3
 All Classes Functions Variables
TimeStamp.cpp
1 /*
2 ** libutil++
3 ** $Id: TimeStamp.cpp 1911 2017-09-02 17:37:35Z sella $
4 ** Copyright (c) 2011-2016 Digital Genesis, LLC. All Rights Reserved.
5 ** Released under the LGPL Version 2.1 License.
6 ** http://www.digitalgenesis.com
7 */
8 
9 static const char rcsid[] __attribute__((used)) = "$Id: TimeStamp.cpp 1911 2017-09-02 17:37:35Z sella $";
10 
11 #include "TimeStamp.h"
12 #include "../util/CommonMacro.h"
13 
14 using namespace sella::variant;
15 
16 TimeStamp::TimeStamp() throw () : Nullable(std::make_shared<int64_t>(0)) { }
17 
18 TimeStamp::TimeStamp(const std::string &value) throw (TypeCastException) : Nullable() {
19  boost::smatch matcher;
20 
21  struct tm stamp;
22  int64_t usec;
23 
24  if (boost::regex_match(value, matcher, TimeStamp::Pattern())) {
25  memset(&stamp, 0, sizeof(stamp));
26 
27  stamp.tm_year = strtol(matcher[1].str().c_str(), NULL, 10) - 1900;
28  stamp.tm_mon = strtol(matcher[2].str().c_str(), NULL, 10) - 1;
29  stamp.tm_mday = strtol(matcher[3].str().c_str(), NULL, 10);
30  stamp.tm_hour = strtol(matcher[4].str().c_str(), NULL, 10);
31  stamp.tm_min = strtol(matcher[7].str().c_str(), NULL, 10);
32  stamp.tm_sec = (matcher.length(9) > 0) ? strtol(matcher[9].str().c_str(), NULL, 10) : 0;
33 
34  usec = mktime(&stamp) * 1000000LL;
35 
36  switch (matcher.length(11)) {
37  case 0:
38  break;
39 
40  case 1:
41  usec += (strtol(matcher[11].str().c_str(), NULL, 10) * 100000LL);
42  break;
43 
44  case 2:
45  usec += (strtol(matcher[11].str().c_str(), NULL, 10) * 10000LL);
46  break;
47 
48  case 3:
49  usec += (strtol(matcher[11].str().c_str(), NULL, 10) * 1000LL);
50  break;
51 
52  case 4:
53  usec += (strtol(matcher[11].str().c_str(), NULL, 10) * 100LL);
54  break;
55 
56  case 5:
57  usec += (strtol(matcher[11].str().c_str(), NULL, 10) * 10LL);
58  break;
59 
60  case 6:
61  usec += (strtol(matcher[11].str().c_str(), NULL, 10));
62  break;
63  }
64  this->value = std::make_shared<int64_t>(usec);
65  } else {
66  THROW(TypeCastException, "unable to cast '%s' to a timestamp value", value.c_str());
67  }
68 }
69 
70 TimeStamp::TimeStamp(int64_t value) throw () : Nullable(std::make_shared<int64_t>(value)) { }
71 
72 TimeStamp::TimeStamp(const TimeStamp &other) throw () : Nullable() {
73  if (this != &other) {
74  if (!other.isNull()) {
75  if (isNull()) {
76  this->value = std::make_shared<int64_t>(other.getUsec());
77  } else {
78  *std::static_pointer_cast<int64_t>(this->value) = *std::static_pointer_cast<int64_t>(other.value);
79  }
80  } else {
81  this->value.reset();
82  }
83  }
84 }
85 
86 TimeStamp::~TimeStamp() throw () { }
87 
88 bool TimeStamp::operator==(const TimeStamp &other) const throw () {
89  return (*std::static_pointer_cast<int64_t>(this->value) == *std::static_pointer_cast<int64_t>(other.value));
90 }
91 
92 bool TimeStamp::operator!=(const TimeStamp &other) const throw () {
93  return !(*this == other);
94 }
95 
96 bool TimeStamp::operator>(const TimeStamp &other) const throw () {
97  return (*std::static_pointer_cast<int64_t>(this->value) > *std::static_pointer_cast<int64_t>(other.value));
98 }
99 
100 bool TimeStamp::operator<(const TimeStamp &other) const throw () {
101  return (*std::static_pointer_cast<int64_t>(this->value) < *std::static_pointer_cast<int64_t>(other.value));
102 }
103 
104 TimeStamp& TimeStamp::operator=(const TimeStamp &other) throw () {
105  if (this != &other) {
106  if (!other.isNull()) {
107  if (isNull()) {
108  this->value = std::make_shared<int64_t>(other.getUsec());
109  } else {
110  *std::static_pointer_cast<int64_t>(this->value) = *std::static_pointer_cast<int64_t>(other.value);
111  }
112  } else {
113  this->value.reset();
114  }
115  }
116 
117  return *this;
118 }
119 
120 TimeStamp& TimeStamp::operator+=(int64_t value) throw () {
121  (*std::static_pointer_cast<int64_t>(this->value)) += value;
122 
123  return *this;
124 }
125 
126 TimeStamp& TimeStamp::operator-=(int64_t value) throw () {
127  (*std::static_pointer_cast<int64_t>(this->value)) -= value;
128 
129  return *this;
130 }
131 
132 TimeStamp& TimeStamp::operator*=(int64_t value) throw () {
133  (*std::static_pointer_cast<int64_t>(this->value)) *= value;
134 
135  return *this;
136 }
137 
138 TimeStamp& TimeStamp::operator/=(int64_t value) throw () {
139  (*std::static_pointer_cast<int64_t>(this->value)) /= value;
140 
141  return *this;
142 }
143 
144 TimeStamp& TimeStamp::operator^=(int64_t value) throw () {
145  (*std::static_pointer_cast<int64_t>(this->value)) = pow((*std::static_pointer_cast<int64_t>(this->value)), value);
146 
147  return *this;
148 }
149 
150 TimeStamp& TimeStamp::operator%=(int64_t value) throw () {
151  (*std::static_pointer_cast<int64_t>(this->value)) %= value;
152 
153  return *this;
154 }
155 
156 TimeStamp& TimeStamp::operator&=(int64_t value) throw () {
157  (*std::static_pointer_cast<int64_t>(this->value)) &= value;
158 
159  return *this;
160 }
161 
162 TimeStamp& TimeStamp::operator|=(int64_t value) throw () {
163  (*std::static_pointer_cast<int64_t>(this->value)) |= value;
164 
165  return *this;
166 }
167 
168 int64_t TimeStamp::getUsec() const throw (UnsupportedOperatorException) {
169  if (isNull()) {
170  THROW(UnsupportedOperatorException, "unable to take reference of null value");
171  }
172 
173  return *std::static_pointer_cast<int64_t>(this->value);
174 }
175 
176 void TimeStamp::msgpack(sella::util::MessagePack &mpack, uint32_t &offset) const throw (TypeCastException) {
177  uint32_t c;
178 
179  if (this->isNull()) {
180  if ((c = mpack.append(offset)) == 0) {
181  THROW(TypeCastException, "Failed to append '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
182  }
183  } else {
184  if ((c = mpack.append(offset, this->str(JSON))) == 0) {
185  THROW(TypeCastException, "Failed to append '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
186  }
187  }
188 
189  offset += c;
190 }
191 
192 void TimeStamp::msgpackBufferSize(size_t &size) const throw () {
193  if (UNLIKELY(isNull())) {
194  size += 1;
195 
196  return;
197  }
198 
199  size += 9;
200 }
201 
202 std::string TimeStamp::str(int type) const throw () {
203  if (UNLIKELY(this->isNull())) {
204  return "null";
205  }
206 
207  char buffer[4096];
208 
209  time_t epoch = this->getUsec() / 1000000LL;
210  struct tm human;
211 
212  gmtime_r(&epoch, &human);
213  snprintf(buffer, sizeof(buffer), "%04d-%02d-%02dT%02d:%02d:%02d.%06lld", human.tm_year + 1900, human.tm_mon + 1, human.tm_mday, human.tm_hour, human.tm_min, human.tm_sec, this->getUsec() % 1000000LL);
214 
215  return buffer;
216 }
217 
218 bool TimeStamp::isType(const char *value, size_t size) throw () {
219  return (size > 10 && value[10] == 'T' && boost::regex_match(std::string(value, size), Pattern()));
220 }
221 
222 /*
223 ** vim: noet ts=3 sw=3
224 */