libutil++  1.9.3
 All Classes Functions Variables
Date.cpp
1 /*
2 ** libutil++
3 ** $Id: Date.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: Date.cpp 1911 2017-09-02 17:37:35Z sella $";
10 
11 #include "Date.h"
12 #include "../util/CommonMacro.h"
13 
14 using namespace sella::variant;
15 
16 Date::Date() throw () : Nullable(std::make_shared<int64_t>(0)) { }
17 
18 Date::Date(const std::string &value) throw (TypeCastException) : Nullable() {
19  boost::smatch matcher;
20  struct tm stamp;
21 
22  if (boost::regex_match(value, matcher, Date::Pattern())) {
23  memset(&stamp, 0, sizeof(stamp));
24 
25  stamp.tm_year = strtol(matcher[1].str().c_str(), NULL, 10) - 1900;
26  stamp.tm_mon = strtol(matcher[2].str().c_str(), NULL, 10) - 1;
27  stamp.tm_mday = strtol(matcher[3].str().c_str(), NULL, 10);
28 
29  this->value = std::make_shared<int64_t>(mktime(&stamp) * 1000000LL);
30  } else {
31  THROW(TypeCastException, "unable to cast '%s' to a date value", value.c_str());
32  }
33 }
34 
35 Date::Date(int64_t value) throw () : Nullable(std::make_shared<int64_t>(value)) { }
36 
37 Date::Date(const Date &other) throw () : Nullable() {
38  if (this != &other) {
39  if (!other.isNull()) {
40  if (isNull()) {
41  this->value = std::make_shared<int64_t>(other.getUsec());
42  } else {
43  *std::static_pointer_cast<int64_t>(this->value) = *std::static_pointer_cast<int64_t>(other.value);
44  }
45  } else {
46  this->value.reset();
47  }
48  }
49 }
50 
51 Date::~Date() throw () { }
52 
53 bool Date::operator==(const Date &other) const throw () {
54  return (*std::static_pointer_cast<int64_t>(this->value) == *std::static_pointer_cast<int64_t>(other.value));
55 }
56 
57 bool Date::operator!=(const Date &other) const throw () {
58  return !(*this == other);
59 }
60 
61 bool Date::operator>(const Date &other) const throw () {
62  return (*std::static_pointer_cast<int64_t>(this->value) > *std::static_pointer_cast<int64_t>(other.value));
63 }
64 
65 bool Date::operator<(const Date &other) const throw () {
66  return (*std::static_pointer_cast<int64_t>(this->value) < *std::static_pointer_cast<int64_t>(other.value));
67 }
68 
69 Date& Date::operator=(const Date &other) throw () {
70  if (this != &other) {
71  if (!other.isNull()) {
72  if (isNull()) {
73  this->value = std::make_shared<int64_t>(other.getUsec());
74  } else {
75  *std::static_pointer_cast<int64_t>(this->value) = *std::static_pointer_cast<int64_t>(other.value);
76  }
77  } else {
78  this->value.reset();
79  }
80  }
81 
82  return *this;
83 }
84 
85 Date& Date::operator+=(int64_t value) throw () {
86  (*std::static_pointer_cast<int64_t>(this->value)) += value;
87 
88  return *this;
89 }
90 
91 Date& Date::operator-=(int64_t value) throw () {
92  (*std::static_pointer_cast<int64_t>(this->value)) -= value;
93 
94  return *this;
95 }
96 
97 Date& Date::operator*=(int64_t value) throw () {
98  (*std::static_pointer_cast<int64_t>(this->value)) *= value;
99 
100  return *this;
101 }
102 
103 Date& Date::operator/=(int64_t value) throw () {
104  (*std::static_pointer_cast<int64_t>(this->value)) /= value;
105 
106  return *this;
107 }
108 
109 Date& Date::operator^=(int64_t value) throw () {
110  (*std::static_pointer_cast<int64_t>(this->value)) = pow((*std::static_pointer_cast<int64_t>(this->value)), value);
111 
112  return *this;
113 }
114 
115 Date& Date::operator%=(int64_t value) throw () {
116  (*std::static_pointer_cast<int64_t>(this->value)) %= value;
117 
118  return *this;
119 }
120 
121 Date& Date::operator&=(int64_t value) throw () {
122  (*std::static_pointer_cast<int64_t>(this->value)) &= value;
123 
124  return *this;
125 }
126 
127 Date& Date::operator|=(int64_t value) throw () {
128  (*std::static_pointer_cast<int64_t>(this->value)) |= value;
129 
130  return *this;
131 }
132 
133 int64_t Date::getUsec() const throw (UnsupportedOperatorException) {
134  if (isNull()) {
135  THROW(UnsupportedOperatorException, "unable to take reference of null value");
136  }
137 
138  return *std::static_pointer_cast<int64_t>(this->value);
139 }
140 
141 void Date::msgpack(sella::util::MessagePack &mpack, uint32_t &offset) const throw (TypeCastException) {
142  uint32_t c;
143 
144  if (UNLIKELY(this->isNull())) {
145  c = mpack.append(offset);
146  } else {
147  c = mpack.append(offset, this->str(JSON));
148  }
149 
150  offset += c;
151 
152  if (UNLIKELY(c == 0)) {
153  THROW(TypeCastException, "Failed to append '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
154  }
155 }
156 
157 void Date::msgpackBufferSize(size_t &size) const throw () {
158  if (UNLIKELY(isNull())) {
159  size += 1;
160 
161  return;
162  }
163 
164  size += 9;
165 }
166 
167 std::string Date::str(int type) const throw () {
168  if (UNLIKELY(this->isNull())) {
169  return "null";
170  }
171 
172  char buffer[4096];
173  time_t epoch = this->getUsec() / 1000000LL;
174  struct tm human;
175 
176  gmtime_r(&epoch, &human);
177  snprintf(buffer, sizeof(buffer), "%04d-%02d-%02d", human.tm_year + 1900, human.tm_mon + 1, human.tm_mday);
178 
179  return buffer;
180 }
181 
182 bool Date::isType(const char *value, size_t size) throw () {
183  return (size == 10 && value[4] == '-' && value[7] == '-' && boost::regex_match(std::string(value, size), Pattern()));
184 }
185 
186 /*
187 ** vim: noet ts=3 sw=3
188 */