Libosmium  2.17.0
Fast and flexible C++ library for working with OpenStreetMap data
Loading...
Searching...
No Matches
timestamp.hpp
Go to the documentation of this file.
1#ifndef OSMIUM_OSM_TIMESTAMP_HPP
2#define OSMIUM_OSM_TIMESTAMP_HPP
3
4/*
5
6This file is part of Osmium (https://osmcode.org/libosmium).
7
8Copyright 2013-2021 Jochen Topf <jochen@topf.org> and others (see README).
9
10Boost Software License - Version 1.0 - August 17th, 2003
11
12Permission is hereby granted, free of charge, to any person or organization
13obtaining a copy of the software and accompanying documentation covered by
14this license (the "Software") to use, reproduce, display, distribute,
15execute, and transmit the Software, and to prepare derivative works of the
16Software, and to permit third-parties to whom the Software is furnished to
17do so, all subject to the following:
18
19The copyright notices in the Software and this entire statement, including
20the above license grant, this restriction and the following disclaimer,
21must be included in all copies of the Software, in whole or in part, and
22all derivative works of the Software, unless such copies or derivative
23works are solely in the form of machine-executable object code generated by
24a source language processor.
25
26THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32DEALINGS IN THE SOFTWARE.
33
34*/
35
37#include <osmium/util/minmax.hpp> // IWYU pragma: keep
38
39#include <array>
40#include <cassert>
41#include <cstdint>
42#include <ctime>
43#include <iosfwd>
44#include <limits>
45#include <stdexcept>
46#include <string>
47#include <type_traits>
48
49namespace osmium {
50
51 namespace detail {
52
53 inline void add_2digit_int_to_string(int value, std::string& out) {
54 assert(value >= 0 && value <= 99);
55 if (value > 9) {
56 const int dec = value / 10;
57 out += static_cast<char>('0' + dec);
58 value -= dec * 10;
59 } else {
60 out += '0';
61 }
62 out += static_cast<char>('0' + value);
63 }
64
65 inline void add_4digit_int_to_string(int value, std::string& out) {
66 assert(value >= 1000 && value <= 9999);
67
68 const int dec1 = value / 1000;
69 out += static_cast<char>('0' + dec1);
70 value -= dec1 * 1000;
71
72 const int dec2 = value / 100;
73 out += static_cast<char>('0' + dec2);
74 value -= dec2 * 100;
75
76 const int dec3 = value / 10;
77 out += static_cast<char>('0' + dec3);
78 value -= dec3 * 10;
79
80 out += static_cast<char>('0' + value);
81 }
82
83 inline time_t parse_timestamp(const char* str) {
84 static const std::array<int, 12> mon_lengths = {{
85 31, 29, 31, 30, 31, 30,
86 31, 31, 30, 31, 30, 31
87 }};
88
89 if (str[ 0] >= '0' && str[ 0] <= '9' &&
90 str[ 1] >= '0' && str[ 1] <= '9' &&
91 str[ 2] >= '0' && str[ 2] <= '9' &&
92 str[ 3] >= '0' && str[ 3] <= '9' &&
93 str[ 4] == '-' &&
94 str[ 5] >= '0' && str[ 5] <= '9' &&
95 str[ 6] >= '0' && str[ 6] <= '9' &&
96 str[ 7] == '-' &&
97 str[ 8] >= '0' && str[ 8] <= '9' &&
98 str[ 9] >= '0' && str[ 9] <= '9' &&
99 str[10] == 'T' &&
100 str[11] >= '0' && str[11] <= '9' &&
101 str[12] >= '0' && str[12] <= '9' &&
102 str[13] == ':' &&
103 str[14] >= '0' && str[14] <= '9' &&
104 str[15] >= '0' && str[15] <= '9' &&
105 str[16] == ':' &&
106 str[17] >= '0' && str[17] <= '9' &&
107 str[18] >= '0' && str[18] <= '9' &&
108 str[19] == 'Z') {
109 std::tm tm; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
110 tm.tm_year = (str[ 0] - '0') * 1000 +
111 (str[ 1] - '0') * 100 +
112 (str[ 2] - '0') * 10 +
113 (str[ 3] - '0') - 1900;
114 tm.tm_mon = (str[ 5] - '0') * 10 + (str[ 6] - '0') - 1;
115 tm.tm_mday = (str[ 8] - '0') * 10 + (str[ 9] - '0');
116 tm.tm_hour = (str[11] - '0') * 10 + (str[12] - '0');
117 tm.tm_min = (str[14] - '0') * 10 + (str[15] - '0');
118 tm.tm_sec = (str[17] - '0') * 10 + (str[18] - '0');
119 tm.tm_wday = 0;
120 tm.tm_yday = 0;
121 tm.tm_isdst = 0;
122 if (tm.tm_year >= 0 &&
123 tm.tm_mon >= 0 && tm.tm_mon <= 11 &&
124 tm.tm_mday >= 1 && tm.tm_mday <= mon_lengths[tm.tm_mon] &&
125 tm.tm_hour >= 0 && tm.tm_hour <= 23 &&
126 tm.tm_min >= 0 && tm.tm_min <= 59 &&
127 tm.tm_sec >= 0 && tm.tm_sec <= 60) {
128#ifndef _WIN32
129 return timegm(&tm);
130#else
131 return _mkgmtime(&tm);
132#endif
133 }
134 }
135 throw std::invalid_argument{std::string{"can not parse timestamp: '"} + str + "'"};
136 }
137
138 } // namespace detail
139
147 class Timestamp {
148
149 uint32_t m_timestamp = 0;
150
151 void to_iso_str(std::string& s) const {
152 std::tm tm; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
153 time_t sse = seconds_since_epoch();
154#ifndef NDEBUG
155 auto result =
156#endif
157#ifndef _WIN32
158 gmtime_r(&sse, &tm);
159 assert(result != nullptr);
160#else
161 gmtime_s(&tm, &sse);
162 assert(result == 0);
163#endif
164
165 detail::add_4digit_int_to_string(tm.tm_year + 1900, s);
166 s += '-';
167 detail::add_2digit_int_to_string(tm.tm_mon + 1, s);
168 s += '-';
169 detail::add_2digit_int_to_string(tm.tm_mday, s);
170 s += 'T';
171 detail::add_2digit_int_to_string(tm.tm_hour, s);
172 s += ':';
173 detail::add_2digit_int_to_string(tm.tm_min, s);
174 s += ':';
175 detail::add_2digit_int_to_string(tm.tm_sec, s);
176 s += 'Z';
177 }
178
179 public:
180
184 constexpr Timestamp() noexcept = default;
185
195 template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
196 constexpr Timestamp(T timestamp) noexcept : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
197 m_timestamp(uint32_t(timestamp)) {
198 }
199
206 explicit Timestamp(const char* timestamp) :
207 m_timestamp(static_cast<uint32_t>(detail::parse_timestamp(timestamp))) {
208 }
209
216 explicit Timestamp(const std::string& timestamp) :
217 Timestamp(timestamp.c_str()) {
218 }
219
224 bool valid() const noexcept {
225 return m_timestamp != 0;
226 }
227
229 explicit constexpr operator bool() const noexcept {
230 return m_timestamp != 0;
231 }
232
234 constexpr time_t seconds_since_epoch() const noexcept {
235 return time_t(m_timestamp);
236 }
237
239 explicit constexpr operator uint32_t() const noexcept {
240 return uint32_t(m_timestamp);
241 }
242
244 explicit constexpr operator uint64_t() const noexcept {
245 return uint64_t(m_timestamp);
246 }
247
253 OSMIUM_DEPRECATED constexpr operator time_t() const noexcept { // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
254 return static_cast<time_t>(m_timestamp);
255 }
256
257 template <typename T>
258 void operator+=(T time_difference) noexcept {
259 m_timestamp += time_difference;
260 }
261
262 template <typename T>
263 void operator-=(T time_difference) noexcept {
264 m_timestamp -= time_difference;
265 }
266
272 std::string to_iso() const {
273 std::string s;
274
275 if (m_timestamp != 0) {
276 to_iso_str(s);
277 }
278
279 return s;
280 }
281
287 std::string to_iso_all() const {
288 std::string s;
289
290 to_iso_str(s);
291
292 return s;
293 }
294
295 }; // class Timestamp
296
301 inline constexpr Timestamp start_of_time() noexcept {
302 return {1};
303 }
304
309 inline constexpr Timestamp end_of_time() noexcept {
310 return {std::numeric_limits<uint32_t>::max()};
311 }
312
313 template <typename TChar, typename TTraits>
314 inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, Timestamp timestamp) {
315 out << timestamp.to_iso();
316 return out;
317 }
318
319 inline bool operator==(const Timestamp& lhs, const Timestamp& rhs) noexcept {
320 return uint32_t(lhs) == uint32_t(rhs);
321 }
322
323 inline bool operator!=(const Timestamp& lhs, const Timestamp& rhs) noexcept {
324 return !(lhs == rhs);
325 }
326
327 inline bool operator<(const Timestamp& lhs, const Timestamp& rhs) noexcept {
328 return uint32_t(lhs) < uint32_t(rhs);
329 }
330
331 inline bool operator>(const Timestamp& lhs, const Timestamp& rhs) noexcept {
332 return rhs < lhs;
333 }
334
335 inline bool operator<=(const Timestamp& lhs, const Timestamp& rhs) noexcept {
336 return !(rhs < lhs);
337 }
338
339 inline bool operator>=(const Timestamp& lhs, const Timestamp& rhs) noexcept {
340 return !(lhs < rhs);
341 }
342
343 template <>
345 return end_of_time();
346 }
347
348 template <>
350 return start_of_time();
351 }
352
353} // namespace osmium
354
355#endif // OSMIUM_OSM_TIMESTAMP_HPP
Definition: timestamp.hpp:147
void to_iso_str(std::string &s) const
Definition: timestamp.hpp:151
std::string to_iso() const
Definition: timestamp.hpp:272
constexpr time_t seconds_since_epoch() const noexcept
Explicit conversion into time_t.
Definition: timestamp.hpp:234
Timestamp(const std::string &timestamp)
Definition: timestamp.hpp:216
constexpr Timestamp() noexcept=default
uint32_t m_timestamp
Definition: timestamp.hpp:149
bool valid() const noexcept
Definition: timestamp.hpp:224
void operator+=(T time_difference) noexcept
Definition: timestamp.hpp:258
void operator-=(T time_difference) noexcept
Definition: timestamp.hpp:263
Timestamp(const char *timestamp)
Definition: timestamp.hpp:206
std::string to_iso_all() const
Definition: timestamp.hpp:287
#define OSMIUM_DEPRECATED
Definition: compatibility.hpp:51
Definition: attr.hpp:342
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
constexpr Timestamp end_of_time() noexcept
Definition: timestamp.hpp:309
bool operator==(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:442
osmium::Timestamp max_op_start_value< osmium::Timestamp >()
Definition: timestamp.hpp:349
bool operator<=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:461
bool operator>(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:457
osmium::Timestamp min_op_start_value< osmium::Timestamp >()
Definition: timestamp.hpp:344
bool operator>=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:465
bool operator!=(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:446
constexpr Timestamp start_of_time() noexcept
Definition: timestamp.hpp:301
std::basic_ostream< TChar, TTraits > & operator<<(std::basic_ostream< TChar, TTraits > &out, const item_type item_type)
Definition: item_type.hpp:185
bool operator<(const Changeset &lhs, const Changeset &rhs)
Definition: changeset.hpp:453
Definition: location.hpp:551