1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 // Defines utilities for the Timestamp and Duration well known types. 32 33 #ifndef GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__ 34 #define GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__ 35 36 #include <cstdint> 37 #include <ctime> 38 #include <ostream> 39 #include <string> 40 #ifdef _MSC_VER 41 #ifdef _XBOX_ONE 42 struct timeval { 43 int64_t tv_sec; /* seconds */ 44 int64_t tv_usec; /* and microseconds */ 45 }; 46 #else 47 #include <winsock2.h> 48 #endif // _XBOX_ONE 49 #else 50 #include <sys/time.h> 51 #endif 52 53 #include <google/protobuf/duration.pb.h> 54 #include <google/protobuf/timestamp.pb.h> 55 56 // Must be included last. 57 #include <google/protobuf/port_def.inc> 58 59 namespace google { 60 namespace protobuf { 61 namespace util { 62 63 // Utility functions for Timestamp and Duration. 64 class PROTOBUF_EXPORT TimeUtil { 65 typedef google::protobuf::Timestamp Timestamp; 66 typedef google::protobuf::Duration Duration; 67 68 public: 69 // The min/max Timestamp/Duration values we support. 70 // 71 // For "0001-01-01T00:00:00Z". 72 static const int64_t kTimestampMinSeconds = -62135596800LL; 73 // For "9999-12-31T23:59:59.999999999Z". 74 static const int64_t kTimestampMaxSeconds = 253402300799LL; 75 static const int64_t kDurationMinSeconds = -315576000000LL; 76 static const int64_t kDurationMaxSeconds = 315576000000LL; 77 78 // Converts Timestamp to/from RFC 3339 date string format. 79 // Generated output will always be Z-normalized and uses 3, 6 or 9 80 // fractional digits as required to represent the exact time. When 81 // parsing, any fractional digits (or none) and any offset are 82 // accepted as long as they fit into nano-seconds precision. 83 // Note that Timestamp can only represent time from 84 // 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. Converting 85 // a Timestamp outside of this range is undefined behavior. 86 // See https://www.ietf.org/rfc/rfc3339.txt 87 // 88 // Example of generated format: 89 // "1972-01-01T10:00:20.021Z" 90 // 91 // Example of accepted format: 92 // "1972-01-01T10:00:20.021-05:00" 93 static std::string ToString(const Timestamp& timestamp); 94 static bool FromString(const std::string& value, Timestamp* timestamp); 95 96 // Converts Duration to/from string format. The string format will contains 97 // 3, 6, or 9 fractional digits depending on the precision required to 98 // represent the exact Duration value. For example: 99 // "1s", "1.010s", "1.000000100s", "-3.100s" 100 // The range that can be represented by Duration is from -315,576,000,000 101 // to +315,576,000,000 inclusive (in seconds). 102 static std::string ToString(const Duration& duration); 103 static bool FromString(const std::string& value, Duration* timestamp); 104 105 #ifdef GetCurrentTime 106 #undef GetCurrentTime // Visual Studio has macro GetCurrentTime 107 #endif 108 // Gets the current UTC time. 109 static Timestamp GetCurrentTime(); 110 // Returns the Time representing "1970-01-01 00:00:00". 111 static Timestamp GetEpoch(); 112 113 // Converts between Duration and integer types. The behavior is undefined if 114 // the input value is not in the valid range of Duration. 115 static Duration NanosecondsToDuration(int64_t nanos); 116 static Duration MicrosecondsToDuration(int64_t micros); 117 static Duration MillisecondsToDuration(int64_t millis); 118 static Duration SecondsToDuration(int64_t seconds); 119 static Duration MinutesToDuration(int64_t minutes); 120 static Duration HoursToDuration(int64_t hours); 121 // Result will be truncated towards zero. For example, "-1.5s" will be 122 // truncated to "-1s", and "1.5s" to "1s" when converting to seconds. 123 // It's undefined behavior if the input duration is not valid or the result 124 // exceeds the range of int64. A duration is not valid if it's not in the 125 // valid range of Duration, or have an invalid nanos value (i.e., larger 126 // than 999999999, less than -999999999, or have a different sign from the 127 // seconds part). 128 static int64_t DurationToNanoseconds(const Duration& duration); 129 static int64_t DurationToMicroseconds(const Duration& duration); 130 static int64_t DurationToMilliseconds(const Duration& duration); 131 static int64_t DurationToSeconds(const Duration& duration); 132 static int64_t DurationToMinutes(const Duration& duration); 133 static int64_t DurationToHours(const Duration& duration); 134 // Creates Timestamp from integer types. The integer value indicates the 135 // time elapsed from Epoch time. The behavior is undefined if the input 136 // value is not in the valid range of Timestamp. 137 static Timestamp NanosecondsToTimestamp(int64_t nanos); 138 static Timestamp MicrosecondsToTimestamp(int64_t micros); 139 static Timestamp MillisecondsToTimestamp(int64_t millis); 140 static Timestamp SecondsToTimestamp(int64_t seconds); 141 // Result will be truncated down to the nearest integer value. For example, 142 // with "1969-12-31T23:59:59.9Z", TimestampToMilliseconds() returns -100 143 // and TimestampToSeconds() returns -1. It's undefined behavior if the input 144 // Timestamp is not valid (i.e., its seconds part or nanos part does not fall 145 // in the valid range) or the return value doesn't fit into int64. 146 static int64_t TimestampToNanoseconds(const Timestamp& timestamp); 147 static int64_t TimestampToMicroseconds(const Timestamp& timestamp); 148 static int64_t TimestampToMilliseconds(const Timestamp& timestamp); 149 static int64_t TimestampToSeconds(const Timestamp& timestamp); 150 151 // Conversion to/from other time/date types. Note that these types may 152 // have a different precision and time range from Timestamp/Duration. 153 // When converting to a lower precision type, the value will be truncated 154 // to the nearest value that can be represented. If the value is 155 // out of the range of the result type, the return value is undefined. 156 // 157 // Conversion to/from time_t 158 static Timestamp TimeTToTimestamp(time_t value); 159 static time_t TimestampToTimeT(const Timestamp& value); 160 161 // Conversion to/from timeval 162 static Timestamp TimevalToTimestamp(const timeval& value); 163 static timeval TimestampToTimeval(const Timestamp& value); 164 static Duration TimevalToDuration(const timeval& value); 165 static timeval DurationToTimeval(const Duration& value); 166 }; 167 168 } // namespace util 169 } // namespace protobuf 170 } // namespace google 171 172 namespace google { 173 namespace protobuf { 174 // Overloaded operators for Duration. 175 // 176 // Assignment operators. 177 PROTOBUF_EXPORT Duration& operator+=(Duration& d1, 178 const Duration& d2); // NOLINT 179 PROTOBUF_EXPORT Duration& operator-=(Duration& d1, 180 const Duration& d2); // NOLINT 181 PROTOBUF_EXPORT Duration& operator*=(Duration& d, int64_t r); // NOLINT 182 PROTOBUF_EXPORT Duration& operator*=(Duration& d, double r); // NOLINT 183 PROTOBUF_EXPORT Duration& operator/=(Duration& d, int64_t r); // NOLINT 184 PROTOBUF_EXPORT Duration& operator/=(Duration& d, double r); // NOLINT 185 // Overload for other integer types. 186 template <typename T> 187 Duration& operator*=(Duration& d, T r) { // NOLINT 188 int64_t x = r; 189 return d *= x; 190 } 191 template <typename T> 192 Duration& operator/=(Duration& d, T r) { // NOLINT 193 int64_t x = r; 194 return d /= x; 195 } 196 PROTOBUF_EXPORT Duration& operator%=(Duration& d1, 197 const Duration& d2); // NOLINT 198 // Relational operators. 199 inline bool operator<(const Duration& d1, const Duration& d2) { 200 if (d1.seconds() == d2.seconds()) { 201 return d1.nanos() < d2.nanos(); 202 } 203 return d1.seconds() < d2.seconds(); 204 } 205 inline bool operator>(const Duration& d1, const Duration& d2) { 206 return d2 < d1; 207 } 208 inline bool operator>=(const Duration& d1, const Duration& d2) { 209 return !(d1 < d2); 210 } 211 inline bool operator<=(const Duration& d1, const Duration& d2) { 212 return !(d2 < d1); 213 } 214 inline bool operator==(const Duration& d1, const Duration& d2) { 215 return d1.seconds() == d2.seconds() && d1.nanos() == d2.nanos(); 216 } 217 inline bool operator!=(const Duration& d1, const Duration& d2) { 218 return !(d1 == d2); 219 } 220 // Additive operators 221 inline Duration operator-(const Duration& d) { 222 Duration result; 223 result.set_seconds(-d.seconds()); 224 result.set_nanos(-d.nanos()); 225 return result; 226 } 227 inline Duration operator+(const Duration& d1, const Duration& d2) { 228 Duration result = d1; 229 return result += d2; 230 } 231 inline Duration operator-(const Duration& d1, const Duration& d2) { 232 Duration result = d1; 233 return result -= d2; 234 } 235 // Multiplicative operators 236 template <typename T> 237 inline Duration operator*(Duration d, T r) { 238 return d *= r; 239 } 240 template <typename T> 241 inline Duration operator*(T r, Duration d) { 242 return d *= r; 243 } 244 template <typename T> 245 inline Duration operator/(Duration d, T r) { 246 return d /= r; 247 } 248 PROTOBUF_EXPORT int64_t operator/(const Duration& d1, const Duration& d2); 249 250 inline Duration operator%(const Duration& d1, const Duration& d2) { 251 Duration result = d1; 252 return result %= d2; 253 } 254 255 inline std::ostream& operator<<(std::ostream& out, const Duration& d) { 256 out << ::PROTOBUF_NAMESPACE_ID::util::TimeUtil::ToString(d); 257 return out; 258 } 259 260 // Overloaded operators for Timestamp 261 // 262 // Assignment operators. 263 PROTOBUF_EXPORT Timestamp& operator+=(Timestamp& t, 264 const Duration& d); // NOLINT 265 PROTOBUF_EXPORT Timestamp& operator-=(Timestamp& t, 266 const Duration& d); // NOLINT 267 // Relational operators. 268 inline bool operator<(const Timestamp& t1, const Timestamp& t2) { 269 if (t1.seconds() == t2.seconds()) { 270 return t1.nanos() < t2.nanos(); 271 } 272 return t1.seconds() < t2.seconds(); 273 } 274 inline bool operator>(const Timestamp& t1, const Timestamp& t2) { 275 return t2 < t1; 276 } 277 inline bool operator>=(const Timestamp& t1, const Timestamp& t2) { 278 return !(t1 < t2); 279 } 280 inline bool operator<=(const Timestamp& t1, const Timestamp& t2) { 281 return !(t2 < t1); 282 } 283 inline bool operator==(const Timestamp& t1, const Timestamp& t2) { 284 return t1.seconds() == t2.seconds() && t1.nanos() == t2.nanos(); 285 } 286 inline bool operator!=(const Timestamp& t1, const Timestamp& t2) { 287 return !(t1 == t2); 288 } 289 // Additive operators. 290 inline Timestamp operator+(const Timestamp& t, const Duration& d) { 291 Timestamp result = t; 292 return result += d; 293 } 294 inline Timestamp operator+(const Duration& d, const Timestamp& t) { 295 Timestamp result = t; 296 return result += d; 297 } 298 inline Timestamp operator-(const Timestamp& t, const Duration& d) { 299 Timestamp result = t; 300 return result -= d; 301 } 302 PROTOBUF_EXPORT Duration operator-(const Timestamp& t1, const Timestamp& t2); 303 304 inline std::ostream& operator<<(std::ostream& out, const Timestamp& t) { 305 out << ::PROTOBUF_NAMESPACE_ID::util::TimeUtil::ToString(t); 306 return out; 307 } 308 309 } // namespace protobuf 310 } // namespace google 311 312 #include <google/protobuf/port_undef.inc> 313 314 #endif // GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__ 315