aboutsummaryrefslogtreecommitdiffhomepage
path: root/absl/time
diff options
context:
space:
mode:
Diffstat (limited to 'absl/time')
-rw-r--r--absl/time/duration.cc5
-rw-r--r--absl/time/format.cc8
-rw-r--r--absl/time/internal/cctz/src/time_zone_impl.cc11
-rw-r--r--absl/time/time.cc14
-rw-r--r--absl/time/time.h9
-rw-r--r--absl/time/time_test.cc24
6 files changed, 66 insertions, 5 deletions
diff --git a/absl/time/duration.cc b/absl/time/duration.cc
index a3ac61a..9a87681 100644
--- a/absl/time/duration.cc
+++ b/absl/time/duration.cc
@@ -906,6 +906,11 @@ bool ParseDuration(const std::string& dur_string, Duration* d) {
return true;
}
+bool AbslParseFlag(absl::string_view text, Duration* dst, std::string*) {
+ return ParseDuration(std::string(text), dst);
+}
+
+std::string AbslUnparseFlag(Duration d) { return FormatDuration(d); }
bool ParseFlag(const std::string& text, Duration* dst, std::string* ) {
return ParseDuration(text, dst);
}
diff --git a/absl/time/format.cc b/absl/time/format.cc
index d6ca860..ebe872c 100644
--- a/absl/time/format.cc
+++ b/absl/time/format.cc
@@ -129,6 +129,14 @@ bool ParseTime(const std::string& format, const std::string& input,
}
// Functions required to support absl::Time flags.
+bool AbslParseFlag(absl::string_view text, absl::Time* t, std::string* error) {
+ return absl::ParseTime(RFC3339_full, std::string(text), absl::UTCTimeZone(),
+ t, error);
+}
+
+std::string AbslUnparseFlag(absl::Time t) {
+ return absl::FormatTime(RFC3339_full, t, absl::UTCTimeZone());
+}
bool ParseFlag(const std::string& text, absl::Time* t, std::string* error) {
return absl::ParseTime(RFC3339_full, text, absl::UTCTimeZone(), t, error);
}
diff --git a/absl/time/internal/cctz/src/time_zone_impl.cc b/absl/time/internal/cctz/src/time_zone_impl.cc
index a26151d..a241e95 100644
--- a/absl/time/internal/cctz/src/time_zone_impl.cc
+++ b/absl/time/internal/cctz/src/time_zone_impl.cc
@@ -14,6 +14,7 @@
#include "time_zone_impl.h"
+#include <deque>
#include <mutex>
#include <string>
#include <unordered_map>
@@ -91,8 +92,14 @@ bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) {
void time_zone::Impl::ClearTimeZoneMapTestOnly() {
std::lock_guard<std::mutex> lock(TimeZoneMutex());
if (time_zone_map != nullptr) {
- // Existing time_zone::Impl* entries are in the wild, so we simply
- // leak them. Future requests will result in reloading the data.
+ // Existing time_zone::Impl* entries are in the wild, so we can't delete
+ // them. Instead, we move them to a private container, where they are
+ // logically unreachable but not "leaked". Future requests will result
+ // in reloading the data.
+ static auto* cleared = new std::deque<const time_zone::Impl*>;
+ for (const auto& element : *time_zone_map) {
+ cleared->push_back(element.second);
+ }
time_zone_map->clear();
}
}
diff --git a/absl/time/time.cc b/absl/time/time.cc
index 6a387bc..60382be 100644
--- a/absl/time/time.cc
+++ b/absl/time/time.cc
@@ -430,9 +430,17 @@ absl::TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour,
}
absl::Time FromTM(const struct tm& tm, absl::TimeZone tz) {
- const CivilSecond cs(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- const auto ti = tz.At(cs);
+ civil_year_t tm_year = tm.tm_year;
+ // Avoids years that are too extreme for CivilSecond to normalize.
+ if (tm_year > 300000000000ll) return InfiniteFuture();
+ if (tm_year < -300000000000ll) return InfinitePast();
+ int tm_mon = tm.tm_mon;
+ if (tm_mon == std::numeric_limits<int>::max()) {
+ tm_mon -= 12;
+ tm_year += 1;
+ }
+ const auto ti = tz.At(CivilSecond(tm_year + 1900, tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec));
return tm.tm_isdst == 0 ? ti.post : ti.pre;
}
diff --git a/absl/time/time.h b/absl/time/time.h
index 9c8f317..0b7312e 100644
--- a/absl/time/time.h
+++ b/absl/time/time.h
@@ -83,6 +83,7 @@ struct timeval;
#include <type_traits>
#include <utility>
+#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
#include "absl/time/civil_time.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
@@ -545,7 +546,11 @@ bool ParseDuration(const std::string& dur_string, Duration* d);
// Support for flag values of type Duration. Duration flags must be specified
// in a format that is valid input for absl::ParseDuration().
+bool AbslParseFlag(absl::string_view text, Duration* dst, std::string* error);
+std::string AbslUnparseFlag(Duration d);
+ABSL_DEPRECATED("Use AbslParseFlag() instead.")
bool ParseFlag(const std::string& text, Duration* dst, std::string* error);
+ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
std::string UnparseFlag(Duration d);
// Time
@@ -815,7 +820,11 @@ std::chrono::system_clock::time_point ToChronoTime(Time);
// Additionally, if you'd like to specify a time as a count of
// seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag
// and add that duration to absl::UnixEpoch() to get an absl::Time.
+bool AbslParseFlag(absl::string_view text, Time* t, std::string* error);
+std::string AbslUnparseFlag(Time t);
+ABSL_DEPRECATED("Use AbslParseFlag() instead.")
bool ParseFlag(const std::string& text, Time* t, std::string* error);
+ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
std::string UnparseFlag(Time t);
// TimeZone
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc
index 37af39d..9c4709e 100644
--- a/absl/time/time_test.cc
+++ b/absl/time/time_test.cc
@@ -795,6 +795,30 @@ TEST(Time, FromTM) {
tm.tm_isdst = 1;
t = FromTM(tm, nyc);
EXPECT_EQ("2014-03-09T03:30:42-04:00", absl::FormatTime(t, nyc)); // DST
+
+ // Adjusts tm to refer to a time with a year larger than 2147483647.
+ tm.tm_year = 2147483647 - 1900 + 1;
+ tm.tm_mon = 6 - 1;
+ tm.tm_mday = 28;
+ tm.tm_hour = 1;
+ tm.tm_min = 2;
+ tm.tm_sec = 3;
+ tm.tm_isdst = -1;
+ t = FromTM(tm, absl::UTCTimeZone());
+ EXPECT_EQ("2147483648-06-28T01:02:03+00:00",
+ absl::FormatTime(t, absl::UTCTimeZone()));
+
+ // Adjusts tm to refer to a time with a very large month.
+ tm.tm_year = 2019 - 1900;
+ tm.tm_mon = 2147483647;
+ tm.tm_mday = 28;
+ tm.tm_hour = 1;
+ tm.tm_min = 2;
+ tm.tm_sec = 3;
+ tm.tm_isdst = -1;
+ t = FromTM(tm, absl::UTCTimeZone());
+ EXPECT_EQ("178958989-08-28T01:02:03+00:00",
+ absl::FormatTime(t, absl::UTCTimeZone()));
}
TEST(Time, TMRoundTrip) {