userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
datetime_light.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/utils/datetime_light.hpp
4
/// @brief Date and Time related converters
5
/// @ingroup userver_universal
6
7
#
include
<
chrono
>
8
#
include
<
cstdint
>
9
#
include
<
optional
>
10
#
include
<
ratio
>
11
#
include
<
stdexcept
>
12
#
include
<
string
>
13
14
#
include
<
cctz
/
civil_time
.
h
>
15
#
include
<
cctz
/
time_zone
.
h
>
16
17
#
include
<
userver
/
utils
/
datetime
/
wall_coarse_clock
.
hpp
>
18
19
USERVER_NAMESPACE_BEGIN
20
21
namespace
utils
::
datetime
{
22
/// @snippet utils/datetime/from_string_saturating_test.cpp kRfc3339Format
23
inline
const
std::string
kRfc3339Format
=
"%Y-%m-%dT%H:%M:%E*S%Ez"
;
24
/// @snippet utils/datetime/from_string_saturating_test.cpp kTaximeterFormat
25
inline
const
std::string
kTaximeterFormat
=
"%Y-%m-%dT%H:%M:%E6SZ"
;
26
inline
constexpr
std::time_t kStartOfTheEpoch = 0;
27
/// @snippet utils/datetime_test.cpp kDefaultDriverTimezone
28
inline
const
std::string
kDefaultDriverTimezone
=
"Europe/Moscow"
;
29
/// @snippet utils/datetime_test.cpp kDefaultTimezone
30
inline
const
std::string
kDefaultTimezone
=
"UTC"
;
31
/// @snippet utils/datetime/from_string_saturating_test.cpp kDefaultFormat
32
inline
const
std::string
kDefaultFormat
=
"%Y-%m-%dT%H:%M:%E*S%z"
;
33
/// @snippet utils/datetime/from_string_saturating_test.cpp kIsoFormat
34
inline
const
std::string
kIsoFormat
=
"%Y-%m-%dT%H:%M:%SZ"
;
35
inline
const
std::string kFractionFormat =
"%Y-%m-%dT%H:%M:%S.%E*f%z"
;
36
37
using
timepair_t = std::pair<std::uint8_t, std::uint8_t>;
38
39
/// Date/time parsing error
40
class
DateParseError
:
public
std::runtime_error {
41
public
:
42
DateParseError(
const
std::string& timestring);
43
};
44
45
/// Timezone information lookup error
46
class
TimezoneLookupError
:
public
std::runtime_error {
47
public
:
48
TimezoneLookupError(
const
std::string& tzname);
49
};
50
51
/// @brief std::chrono::system_clock::now() that could be mocked
52
///
53
/// Returns last time point passed to utils::datetime::MockNowSet(), or
54
/// std::chrono::system_clock::now() if the timepoint is not mocked.
55
std::chrono::system_clock::time_point
Now
()
noexcept
;
56
57
/// @brief Returns std::chrono::system_clock::time_point from the start of the
58
/// epoch
59
std::chrono::system_clock::time_point
Epoch
()
noexcept
;
60
61
/// @brief std::chrono::steady_clock::now() that could be mocked
62
///
63
/// Returns last time point passed to utils::datetime::MockNowSet(), or
64
/// std::chrono::steady_clock::now() if the timepoint is not mocked.
65
///
66
/// It is only intended for period-based structures/algorithms testing.
67
///
68
/// @warning You MUST NOT pass time points received from this function outside
69
/// of your own code. Otherwise this will break your service in production.
70
std::chrono::steady_clock::time_point
SteadyNow
()
noexcept
;
71
72
/// @brief utils::datetime::WallCoarseClock::now() that could be mocked
73
///
74
/// Returns last time point passed to utils::datetime::MockNowSet(), or utils::datetime::WallCoarseClock::now() if
75
/// the timepoint is not mocked.
76
WallCoarseClock::time_point
WallCoarseNow
()
noexcept
;
77
78
// See the comment to SteadyNow()
79
class
SteadyClock
:
public
std::chrono::steady_clock {
80
public
:
81
using
time_point = std::chrono::steady_clock::time_point;
82
83
static
time_point now() {
return
SteadyNow
(
)
; }
84
};
85
86
/// @brief Returns true if the time is in range; works over midnight too
87
bool
IsTimeBetween
(
88
int
hour,
89
int
min,
90
int
hour_from,
91
int
min_from,
92
int
hour_to,
93
int
min_to,
94
bool
include_time_to =
false
95
)
noexcept
;
96
97
/// @brief Extracts time point from a string, guessing the format
98
/// @note Use GuessStringtime instead
99
/// @throws utils::datetime::DateParseError
100
std::chrono::system_clock::time_point
DoGuessStringtime
(
const
std::string& timestring,
const
cctz::time_zone& timezone);
101
102
/// @brief Returns time in a string of specified format in local timezone
103
/// @see kRfc3339Format, kTaximeterFormat, kStartOfTheEpoch,
104
/// kDefaultDriverTimezone, kDefaultTimezone, kDefaultFormat, kIsoFormat
105
std::string
LocalTimezoneTimestring
(std::time_t timestamp,
const
std::string& format =
kDefaultFormat
);
106
107
/// @brief Returns time in a string of specified format in UTC timezone
108
/// @see kRfc3339Format, kTaximeterFormat, kStartOfTheEpoch,
109
/// kDefaultDriverTimezone, kDefaultTimezone, kDefaultFormat, kIsoFormat
110
std::string
UtcTimestring
(std::time_t timestamp,
const
std::string& format =
kDefaultFormat
);
111
112
std::string Timestring(std::chrono::system_clock::time_point tp);
113
114
/// @brief Returns time in a string of specified format in local timezone
115
/// @see kRfc3339Format, kTaximeterFormat, kStartOfTheEpoch,
116
/// kDefaultDriverTimezone, kDefaultTimezone, kDefaultFormat, kIsoFormat
117
std::string
LocalTimezoneTimestring
(
118
std::chrono::system_clock::time_point tp,
119
const
std::string& format =
kDefaultFormat
120
);
121
122
/// @brief Returns time in a string of specified format in UTC timezone
123
/// @see kRfc3339Format, kTaximeterFormat, kStartOfTheEpoch,
124
/// kDefaultDriverTimezone, kDefaultTimezone, kDefaultFormat, kIsoFormat
125
/// @throws std::runtime_error if tp does not fit into @c std::chrono::hours
126
template
<
class
Duration>
127
std::string
UtcTimestring
(
128
std::chrono::time_point<std::chrono::system_clock, Duration> tp,
129
const
std::string& format =
kDefaultFormat
130
) {
131
using
quotient = std::ratio_divide<
typename
Duration::period, std::chrono::hours::period>;
132
if
constexpr
(quotient::num <= quotient::den) {
133
return
cctz::format(format, tp, cctz::utc_time_zone());
134
}
else
{
135
// cctz cannot handle time_points with duration more than hours
136
const
auto
days = tp.time_since_epoch();
137
if
(days > std::chrono::duration_cast<Duration>(std::chrono::hours::max())) {
138
throw
std::runtime_error(
"tp does not find std::chrono::hours"
);
139
}
140
const
std::chrono::time_point<std::chrono::system_clock, std::chrono::hours>
141
tp_hours(std::chrono::duration_cast<std::chrono::hours>(days));
142
return
cctz::format(format, tp_hours, cctz::utc_time_zone());
143
}
144
}
145
146
/// @brief Extracts time point from a string of a specified format in local timezone
147
/// @throws utils::datetime::DateParseError
148
/// @see kRfc3339Format, kTaximeterFormat, kStartOfTheEpoch,
149
/// kDefaultDriverTimezone, kDefaultTimezone, kDefaultFormat, kIsoFormat
150
std::chrono::system_clock::time_point
LocalTimezoneStringtime
(
151
const
std::string& timestring,
152
const
std::string& format =
kDefaultFormat
153
);
154
155
/// @brief Extracts time point from a string of a specified format in UTC timezone
156
/// @throws utils::datetime::DateParseError
157
/// @see kRfc3339Format, kTaximeterFormat, kStartOfTheEpoch,
158
/// kDefaultDriverTimezone, kDefaultTimezone, kDefaultFormat, kIsoFormat
159
std::chrono::system_clock::time_point
UtcStringtime
(
160
const
std::string& timestring,
161
const
std::string& format =
kDefaultFormat
162
);
163
164
/// @brief Extracts time point from a string of a kDefaultFormat format in UTC timezone
165
/// @throws utils::datetime::DateParseError
166
std::chrono::system_clock::time_point
Stringtime
(
const
std::string& timestring);
167
168
/// @brief Extracts time point from a string of a specified format
169
/// @see kRfc3339Format, kTaximeterFormat, kStartOfTheEpoch,
170
/// kDefaultDriverTimezone, kDefaultTimezone, kDefaultFormat, kIsoFormat
171
std::optional<std::chrono::system_clock::time_point>
OptionalStringtime
(
172
const
std::string& timestring,
173
const
cctz::time_zone& timezone,
174
const
std::string& format
175
);
176
177
/// @brief Extracts time point from a string of a kDefaultFormat format in UTC timezone
178
/// @throws utils::datetime::DateParseError
179
std::optional<std::chrono::system_clock::time_point>
OptionalStringtime
(
const
std::string& timestring);
180
181
/// @brief Extracts time point from a string, guessing the format
182
/// @throws utils::datetime::DateParseError
183
std::chrono::system_clock::time_point
GuessLocalTimezoneStringtime
(
const
std::string& timestamp);
184
185
/// @brief Converts time point to std::time_t
186
///
187
/// Example:
188
///
189
/// @snippet utils/datetime_test.cpp UtcTimestring C time example
190
std::
time_t
Timestamp
(std::chrono::system_clock::time_point tp)
noexcept
;
191
192
/// @brief Returned current time as std::time_t; could be mocked
193
std::
time_t
Timestamp
()
noexcept
;
194
195
/// @brief Parse day time in hh:mm[:ss] format
196
/// @param str day time in format hh:mm[:ss]
197
/// @return number of second since start of day
198
std::
uint32_t
ParseDayTime
(
const
std::string& str);
199
200
/// @brief Converts absolute time in std::chrono::system_clock::time_point to
201
/// a civil time of a local timezone.
202
cctz::civil_second
LocalTimezoneLocalize
(
const
std::chrono::system_clock::time_point& tp);
203
204
/// @brief Converts a civil time in a local timezone into an absolute time.
205
std::
time_t
LocalTimezoneUnlocalize
(
const
cctz::civil_second& local_tp);
206
207
/// @brief Returns string with time in ISO8601 format "YYYY-MM-DDTHH:MM:SS+0000"
208
/// @param timestamp unix timestamp
209
std::string
TimestampToString
(std::time_t timestamp);
210
211
/// @brief Convert time_point to DotNet ticks
212
/// @param tp time point
213
/// @return number of 100-nanosecond intervals between current date and 01/01/0001
214
///
215
/// Example:
216
///
217
/// @snippet utils/datetime_test.cpp TimePointToTicks example
218
std::
int64_t
TimePointToTicks
(
const
std::chrono::system_clock::time_point& tp)
noexcept
;
219
220
/// @brief Convert DotNet ticks to a time point
221
std::chrono::system_clock::time_point
TicksToTimePoint
(std::int64_t ticks)
noexcept
;
222
223
/// @brief Compute (a - b) with a specified duration
224
template
<
class
Duration,
class
Clock>
225
double
CalcTimeDiff
(
const
std::chrono::time_point<Clock>& a,
const
std::chrono::time_point<Clock>& b) {
226
const
auto
duration_a = a.time_since_epoch();
227
const
auto
duration_b = b.time_since_epoch();
228
return
std::chrono::duration_cast<Duration>(duration_a - duration_b).count();
229
}
230
231
}
// namespace utils::datetime
232
233
USERVER_NAMESPACE_END
userver
utils
datetime_light.hpp
Generated on
for userver by
Doxygen
1.17.0