1 /* Copyright (c) 2015, 2021, Oracle and/or its affiliates. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 22 23 24 #ifndef _MYSQLX_DATETIME_H_ 25 #define _MYSQLX_DATETIME_H_ 26 27 #include <string> 28 #include <stdint.h> 29 #include <ostream> 30 #include <ios> 31 #include <iomanip> 32 #include <sstream> 33 34 namespace mysqlx 35 { 36 class Time 37 { 38 public: Time()39 Time() : m_negate(false), m_hour(0), m_minutes(0), m_seconds(0), 40 m_useconds(0), m_valid(false) 41 {} 42 43 Time(bool negate_, 44 uint32_t hour_, 45 uint8_t minutes_, 46 uint8_t seconds_, 47 uint32_t useconds_ = 0) m_negate(negate_)48 : m_negate(negate_), m_hour(hour_), m_minutes(minutes_), 49 m_seconds(seconds_), m_useconds(useconds_), m_valid(true) 50 { 51 if (minutes_ > 59 || seconds_ > 59 || useconds_ >= 1000000) 52 m_valid = false; 53 } 54 valid()55 bool valid() const 56 { 57 return m_valid; 58 } 59 60 operator bool () const 61 { 62 return m_valid; 63 } 64 negate()65 bool negate() const { return m_negate; } 66 hour()67 uint32_t hour() const { return m_hour; } minutes()68 uint8_t minutes() const { return m_minutes; } seconds()69 uint8_t seconds() const { return m_seconds; } useconds()70 uint32_t useconds() const { return m_useconds; } 71 to_string()72 std::string to_string() const 73 { 74 std::stringstream ss; 75 76 if (!valid()) 77 return ""; 78 79 ss.fill('0'); 80 ss << (negate() ? "-" : "") 81 << std::setw(2) << static_cast<int>(hour()) 82 << ":" << std::setw(2) << static_cast<int>(minutes()) 83 << ":" << std::setw(2) << static_cast<int>(seconds()) 84 << us_to_str(useconds()); 85 86 return ss.str(); 87 } 88 us_to_str(uint32_t val)89 static std::string us_to_str(uint32_t val) 90 { 91 if (0 == val) 92 return ""; 93 94 std::stringstream ss; 95 ss << "." << val; 96 std::string result = ss.str(); 97 size_t last = result.find_last_not_of('0') + 1; 98 result.erase(last); 99 100 return result; 101 } 102 103 private: 104 bool m_negate; 105 uint32_t m_hour; 106 uint8_t m_minutes; 107 uint8_t m_seconds; 108 uint32_t m_useconds; 109 bool m_valid; 110 }; 111 112 113 class DateTime 114 { 115 public: 116 DateTime(uint16_t year_, 117 uint8_t month_, 118 uint8_t day_, 119 120 uint8_t hour_ = 0xff, 121 uint8_t minutes_ = 0, 122 uint8_t seconds_ = 0, 123 uint32_t useconds_ = 0) m_year(year_)124 : m_year(year_), m_month(month_), m_day(day_), 125 m_hour(hour_), m_minutes(minutes_), m_seconds(seconds_), 126 m_useconds(useconds_), m_valid(true) 127 { 128 if (year_ > 9999 || month_ > 12 || day_ > 31) 129 m_valid = false; 130 if (hour_ != 0xff) 131 { 132 if (hour_ > 23 || minutes_ > 59 || seconds_ > 59 || useconds_ >= 1000000) 133 m_valid = false; 134 } 135 } 136 DateTime()137 DateTime() {} 138 valid()139 bool valid() const 140 { 141 return m_valid; 142 } 143 144 operator bool () const 145 { 146 return m_valid; 147 } 148 has_time()149 bool has_time() const 150 { 151 return m_hour != 0xff; 152 } 153 to_string()154 std::string to_string() const 155 { 156 if (!valid()) 157 return ""; 158 159 std::stringstream ss; 160 ss.fill('0'); 161 162 ss << std::setw(4) << year() << "/" 163 << std::setw(2) << static_cast<int>(month()) << "/" 164 << std::setw(2) << static_cast<int>(day()); 165 166 if (has_time()) 167 { 168 ss << " " << std::setw(2) << static_cast<int>(hour()) 169 << ":" << std::setw(2) << static_cast<int>(minutes()) 170 << ":" << std::setw(2) << static_cast<int>(seconds()) 171 << Time::us_to_str(useconds()); 172 } 173 174 return ss.str(); 175 } 176 year()177 uint16_t year() const { return m_year; } month()178 uint8_t month() const { return m_month; } day()179 uint8_t day() const { return m_day; } 180 hour()181 uint8_t hour() const { return m_hour; } minutes()182 uint8_t minutes() const { return m_minutes; } seconds()183 uint8_t seconds() const { return m_seconds; } useconds()184 uint32_t useconds() const { return m_useconds; } time()185 Time time() const { return Time(false, m_hour, m_minutes, m_seconds, m_useconds); } 186 187 private: 188 uint16_t m_year; 189 uint8_t m_month; 190 uint8_t m_day; 191 192 uint8_t m_hour; 193 uint8_t m_minutes; 194 uint8_t m_seconds; 195 uint32_t m_useconds; 196 197 bool m_valid; 198 }; 199 200 201 inline std::ostream & operator<<(std::ostream &os, const DateTime &v) 202 { 203 if (v) 204 { 205 os << v.to_string(); 206 } 207 return os; 208 } 209 210 inline std::ostream & operator<<(std::ostream &os, const Time &v) 211 { 212 if (v) 213 { 214 os << v.to_string(); 215 } 216 return os; 217 } 218 } 219 220 #endif 221