Skip to content

Commit 8e1aeee

Browse files
author
vitaly2020
committed
feat universal: add optional string to datetime parser
add optional string to datetime parser Tests: протестировано utest d3e81113f213a3c4a1cb14061c66d244205d1ace
1 parent 8a264bb commit 8e1aeee

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

universal/include/userver/utils/datetime.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/// @ingroup userver_universal
66

77
#include <chrono>
8+
#include <optional>
89
#include <stdexcept>
910
#include <string>
1011

@@ -138,6 +139,16 @@ std::chrono::system_clock::time_point GuessStringtime(
138139
std::chrono::system_clock::time_point GuessLocalTimezoneStringtime(
139140
const std::string& timestamp);
140141

142+
/// @brief Returns optional time in a string of specified format
143+
/// Example:
144+
/// @snippet utils/datetime/datetime_test.cpp OptionalTimestring example
145+
/// @see kRfc3339Format, kTaximeterFormat, kStartOfTheEpoch,
146+
/// kDefaultDriverTimezone, kDefaultTimezone, kDefaultFormat, kIsoFormat
147+
std::optional<std::chrono::system_clock::time_point> OptionalStringtime(
148+
const std::string& timestring,
149+
const std::string& timezone = kDefaultTimezone,
150+
const std::string& format = kDefaultFormat);
151+
141152
/// @brief Converts time point to std::time_t
142153
/// Example:
143154
/// @snippet utils/datetime/datetime_test.cpp Timestring C time example

universal/src/utils/datetime.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,25 @@ constexpr int64_t k100NanosecondsIntervalsBetweenDotNetAndPosixTimeStart =
2828
62135596800L * 10000000L; // sec to 100nanosec
2929
constexpr int64_t kNanosecondsIs100Nanoseconds = 100;
3030

31-
cctz::time_zone GetTimezone(const std::string& tzname) {
31+
std::optional<cctz::time_zone> GetOptionalTimezone(const std::string& tzname) {
3232
#if defined(BSD) && !defined(__APPLE__)
33-
if (tzname == "GMT") return GetTimezone("UTC");
33+
if (tzname == "GMT") return GetOptionalTimezone("UTC");
3434
#endif
3535
cctz::time_zone tz;
3636
if (!load_time_zone(tzname, &tz)) {
37-
throw TimezoneLookupError(tzname);
37+
return std::nullopt;
3838
}
3939
return tz;
4040
}
4141

42+
cctz::time_zone GetTimezone(const std::string& tzname) {
43+
auto tz = GetOptionalTimezone(tzname);
44+
if (!tz.has_value()) {
45+
throw TimezoneLookupError(tzname);
46+
}
47+
return *tz;
48+
}
49+
4250
const cctz::time_zone& GetLocalTimezone() {
4351
static const cctz::time_zone kLocalTz = cctz::local_time_zone();
4452
return kLocalTz;
@@ -107,6 +115,16 @@ std::string Timestring(std::chrono::system_clock::time_point tp,
107115
return cctz::format(format, tp, GetTimezone(timezone));
108116
}
109117

118+
std::optional<std::chrono::system_clock::time_point> OptionalStringtime(
119+
const std::string& timestring, const std::string& timezone,
120+
const std::string& format) {
121+
auto tz = GetOptionalTimezone(timezone);
122+
if (!tz.has_value()) {
123+
return std::nullopt;
124+
}
125+
return OptionalStringtime(timestring, *tz, format);
126+
}
127+
110128
std::string LocalTimezoneTimestring(std::chrono::system_clock::time_point tp,
111129
const std::string& format) {
112130
return cctz::format(format, tp, GetLocalTimezone());

universal/src/utils/datetime/datetime_test.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ TEST(Datetime, Stringtime) {
1616
/// [Stringtime example]
1717
}
1818

19+
TEST(Datetime, OptionalStringtime) {
20+
/// [OptionalStringtime example]
21+
const auto tp = utils::datetime::Stringtime("2014-03-17T02:47:07+0000");
22+
EXPECT_EQ(
23+
utils::datetime::OptionalStringtime("2014-03-17T02:47:07+0000").value(),
24+
tp);
25+
/// [OptionalStringtime example]
26+
}
27+
1928
TEST(Datetime, Timestring) {
2029
/// [Timestring example]
2130
const auto tp = utils::datetime::Stringtime("2014-03-17T02:47:07+0000");
@@ -81,6 +90,19 @@ TEST(Datetime, kDefaultTimezone) {
8190
/// [kDefaultTimezone]
8291
}
8392

93+
TEST(Datetime, kIncorrectDatetimeFormat) {
94+
/// [kIncorrectDatetimeFormat]
95+
EXPECT_FALSE(utils::datetime::OptionalStringtime("20140317T02:47:07+0000")
96+
.has_value());
97+
/// [kIncorrectDatetimeFormat]
98+
}
99+
100+
TEST(Datetime, kEmptyDatetime) {
101+
/// [kEmptyDatetime]
102+
EXPECT_FALSE(utils::datetime::OptionalStringtime("").has_value());
103+
/// [kEmptyDatetime]
104+
}
105+
84106
} // namespace
85107

86108
USERVER_NAMESPACE_END

0 commit comments

Comments
 (0)