summaryrefslogtreecommitdiff
path: root/absl/time
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2020-05-26 10:57:33 -0700
committerGravatar Derek Mauro <dmauro@google.com>2020-05-26 14:45:38 -0400
commit33caf1097ecce4fe892567462fa8821d477854b4 (patch)
tree27eecef4f8c5638857b134ea117c3bd20a980b96 /absl/time
parentcf1a02e2dc5a1bc9d095f4c996306de448ca200f (diff)
Export of internal Abseil changes
-- 7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 313226473 -- 1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>: Migrate internal interface to use mutable references. PiperOrigin-RevId: 312931131 -- 96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>: Remove random/internal/distributions.h This file was something of an historical artifact. All of the related code has either been removed or migraged, and so the only remaining type belongs with uniform_helper.h, as it is used to infer the return type of the absl::Uniform method in a few cases. PiperOrigin-RevId: 312878173 -- 6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>: Release the StrFormat test case for Cords to open source. PiperOrigin-RevId: 312707974 -- 34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>: Let Cord::Cord(string&&), Cord::operator=(string&&), Cord::Append(string&&), and Cord::Prepend(string&&) steal string data and embed it into the Cord as a single external chunk, instead of copying it into flat chunks (at most 4083-byte each). Stealing string data is faster, but it creates a long chunk, which leads to a higher more memory usage if its subcords are created and outlive the whole Cord. These functions revert to copying the data if any of the following conditions holds: - string size is at most kMaxBytesToCopy (511), to avoid the overhead of an external chunk for short strings; - less than half of string capacity is used, to avoid pinning to much unused memory. PiperOrigin-RevId: 312683785 GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923 Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
Diffstat (limited to 'absl/time')
-rw-r--r--absl/time/internal/cctz/include/cctz/time_zone.h3
-rw-r--r--absl/time/internal/cctz/src/cctz_benchmark.cc16
-rw-r--r--absl/time/internal/cctz/src/time_zone_format.cc23
-rw-r--r--absl/time/internal/cctz/src/time_zone_format_test.cc18
-rw-r--r--absl/time/internal/cctz/src/time_zone_lookup_test.cc2
5 files changed, 45 insertions, 17 deletions
diff --git a/absl/time/internal/cctz/include/cctz/time_zone.h b/absl/time/internal/cctz/include/cctz/time_zone.h
index d4ea90ef..b33e0c0a 100644
--- a/absl/time/internal/cctz/include/cctz/time_zone.h
+++ b/absl/time/internal/cctz/include/cctz/time_zone.h
@@ -292,6 +292,7 @@ bool parse(const std::string&, const std::string&, const time_zone&,
// - %E#f - Fractional seconds with # digits of precision
// - %E*f - Fractional seconds with full precision (a literal '*')
// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
+// - %ET - The RFC3339 "date-time" separator "T"
//
// Note that %E0S behaves like %S, and %E0f produces no characters. In
// contrast %E*f always produces at least one digit, which may be '0'.
@@ -321,7 +322,7 @@ inline std::string format(const std::string& fmt, const time_point<D>& tp,
// returns the corresponding time_point. Uses strftime()-like formatting
// options, with the same extensions as cctz::format(), but with the
// exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez
-// and %E*z also accept the same inputs.
+// and %E*z also accept the same inputs. %ET accepts either 'T' or 't'.
//
// %Y consumes as many numeric characters as it can, so the matching data
// should always be terminated with a non-numeric. %E4Y always consumes
diff --git a/absl/time/internal/cctz/src/cctz_benchmark.cc b/absl/time/internal/cctz/src/cctz_benchmark.cc
index a402760d..4e39188f 100644
--- a/absl/time/internal/cctz/src/cctz_benchmark.cc
+++ b/absl/time/internal/cctz/src/cctz_benchmark.cc
@@ -97,8 +97,8 @@ void BM_PrevWeekday(benchmark::State& state) {
}
BENCHMARK(BM_PrevWeekday);
-const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
-const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
+const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez";
+const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez";
const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z";
const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z";
@@ -991,12 +991,12 @@ void BM_Time_FromCivilDay0_Libc(benchmark::State& state) {
BENCHMARK(BM_Time_FromCivilDay0_Libc);
const char* const kFormats[] = {
- RFC1123_full, // 0
- RFC1123_no_wday, // 1
- RFC3339_full, // 2
- RFC3339_sec, // 3
- "%Y-%m-%dT%H:%M:%S", // 4
- "%Y-%m-%d", // 5
+ RFC1123_full, // 0
+ RFC1123_no_wday, // 1
+ RFC3339_full, // 2
+ RFC3339_sec, // 3
+ "%Y-%m-%d%ET%H:%M:%S", // 4
+ "%Y-%m-%d", // 5
};
const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
diff --git a/absl/time/internal/cctz/src/time_zone_format.cc b/absl/time/internal/cctz/src/time_zone_format.cc
index 179975e0..a4428632 100644
--- a/absl/time/internal/cctz/src/time_zone_format.cc
+++ b/absl/time/internal/cctz/src/time_zone_format.cc
@@ -290,6 +290,7 @@ const std::int_fast64_t kExp10[kDigits10_64 + 1] = {
// - %E#S - Seconds with # digits of fractional precision
// - %E*S - Seconds with full fractional precision (a literal '*')
// - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
+// - %ET - The RFC3339 "date-time" separator "T"
//
// The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are
// handled internally for performance reasons. strftime(3) is slow due to
@@ -448,7 +449,14 @@ std::string format(const std::string& format, const time_point<seconds>& tp,
if (*cur != 'E' || ++cur == end) continue;
// Format our extensions.
- if (*cur == 'z') {
+ if (*cur == 'T') {
+ // Formats %ET.
+ if (cur - 2 != pending) {
+ FormatTM(&result, std::string(pending, cur - 2), tm);
+ }
+ result.append("T");
+ pending = ++cur;
+ } else if (*cur == 'z') {
// Formats %Ez.
if (cur - 2 != pending) {
FormatTM(&result, std::string(pending, cur - 2), tm);
@@ -551,7 +559,7 @@ const char* ParseOffset(const char* dp, const char* mode, int* offset) {
} else {
dp = nullptr;
}
- } else if (first == 'Z') { // Zulu
+ } else if (first == 'Z' || first == 'z') { // Zulu
*offset = 0;
} else {
dp = nullptr;
@@ -607,7 +615,7 @@ const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) {
// Uses strptime(3) to parse the given input. Supports the same extended
// format specifiers as format(), although %E#S and %E*S are treated
// identically (and similarly for %E#f and %E*f). %Ez and %E*z also accept
-// the same inputs.
+// the same inputs. %ET accepts either 'T' or 't'.
//
// The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are
// handled internally so that we can normally avoid strptime() altogether
@@ -742,6 +750,15 @@ bool parse(const std::string& format, const std::string& input,
data = (*data == '%' ? data + 1 : nullptr);
continue;
case 'E':
+ if (fmt[0] == 'T') {
+ if (*data == 'T' || *data == 't') {
+ ++data;
+ ++fmt;
+ } else {
+ data = nullptr;
+ }
+ continue;
+ }
if (fmt[0] == 'z' || (fmt[0] == '*' && fmt[1] == 'z')) {
data = ParseOffset(data, ":", &offset);
if (data != nullptr) saw_offset = true;
diff --git a/absl/time/internal/cctz/src/time_zone_format_test.cc b/absl/time/internal/cctz/src/time_zone_format_test.cc
index 87382e15..13a4227e 100644
--- a/absl/time/internal/cctz/src/time_zone_format_test.cc
+++ b/absl/time/internal/cctz/src/time_zone_format_test.cc
@@ -48,8 +48,8 @@ namespace {
EXPECT_STREQ(zone, al.abbr); \
} while (0)
-const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
-const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
+const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez";
+const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez";
const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z";
const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z";
@@ -1379,10 +1379,20 @@ TEST(Parse, RFC3339Format) {
EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00+00:00", tz, &tp));
ExpectTime(tp, tz, 2014, 2, 12, 20, 21, 0, 0, false, "UTC");
- // Check that %Ez also accepts "Z" as a synonym for "+00:00".
+ // Check that %ET also accepts "t".
time_point<chrono::nanoseconds> tp2;
- EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00Z", tz, &tp2));
+ EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12t20:21:00+00:00", tz, &tp2));
EXPECT_EQ(tp, tp2);
+
+ // Check that %Ez also accepts "Z" as a synonym for "+00:00".
+ time_point<chrono::nanoseconds> tp3;
+ EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00Z", tz, &tp3));
+ EXPECT_EQ(tp, tp3);
+
+ // Check that %Ez also accepts "z" as a synonym for "+00:00".
+ time_point<chrono::nanoseconds> tp4;
+ EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00z", tz, &tp4));
+ EXPECT_EQ(tp, tp4);
}
TEST(Parse, MaxRange) {
diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
index 0b0c1a3b..8f7ab154 100644
--- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc
+++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
@@ -933,7 +933,7 @@ TEST(MakeTime, Normalization) {
// NOTE: Run this with -ftrapv to detect overflow problems.
TEST(MakeTime, SysSecondsLimits) {
- const char RFC3339[] = "%Y-%m-%dT%H:%M:%S%Ez";
+ const char RFC3339[] = "%Y-%m-%d%ET%H:%M:%S%Ez";
const time_zone utc = utc_time_zone();
const time_zone east = fixed_time_zone(chrono::hours(14));
const time_zone west = fixed_time_zone(-chrono::hours(14));