format.cc
Go to the documentation of this file.
1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <string.h>
16 #include <cctype>
17 #include <cstdint>
18 
20 #include "absl/time/time.h"
21 
23 
24 namespace absl {
25 
26 extern const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
27 extern const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
28 
29 extern const char RFC1123_full[] = "%a, %d %b %E4Y %H:%M:%S %z";
30 extern const char RFC1123_no_wday[] = "%d %b %E4Y %H:%M:%S %z";
31 
32 namespace {
33 
34 const char kInfiniteFutureStr[] = "infinite-future";
35 const char kInfinitePastStr[] = "infinite-past";
36 
37 struct cctz_parts {
40 };
41 
42 inline cctz::time_point<cctz::seconds> unix_epoch() {
43  return std::chrono::time_point_cast<cctz::seconds>(
44  std::chrono::system_clock::from_time_t(0));
45 }
46 
47 // Splits a Time into seconds and femtoseconds, which can be used with CCTZ.
48 // Requires that 't' is finite. See duration.cc for details about rep_hi and
49 // rep_lo.
50 cctz_parts Split(absl::Time t) {
51  const auto d = time_internal::ToUnixDuration(t);
52  const int64_t rep_hi = time_internal::GetRepHi(d);
53  const int64_t rep_lo = time_internal::GetRepLo(d);
54  const auto sec = unix_epoch() + cctz::seconds(rep_hi);
55  const auto fem = cctz::detail::femtoseconds(rep_lo * (1000 * 1000 / 4));
56  return {sec, fem};
57 }
58 
59 // Joins the given seconds and femtoseconds into a Time. See duration.cc for
60 // details about rep_hi and rep_lo.
61 absl::Time Join(const cctz_parts& parts) {
62  const int64_t rep_hi = (parts.sec - unix_epoch()).count();
63  const uint32_t rep_lo = parts.fem.count() / (1000 * 1000 / 4);
64  const auto d = time_internal::MakeDuration(rep_hi, rep_lo);
66 }
67 
68 } // namespace
69 
70 std::string FormatTime(const std::string& format, absl::Time t,
71  absl::TimeZone tz) {
72  if (t == absl::InfiniteFuture()) return kInfiniteFutureStr;
73  if (t == absl::InfinitePast()) return kInfinitePastStr;
74  const auto parts = Split(t);
75  return cctz::detail::format(format, parts.sec, parts.fem,
76  cctz::time_zone(tz));
77 }
78 
79 std::string FormatTime(absl::Time t, absl::TimeZone tz) {
80  return FormatTime(RFC3339_full, t, tz);
81 }
82 
83 std::string FormatTime(absl::Time t) {
84  return absl::FormatTime(RFC3339_full, t, absl::LocalTimeZone());
85 }
86 
87 bool ParseTime(const std::string& format, const std::string& input,
88  absl::Time* time, std::string* err) {
89  return absl::ParseTime(format, input, absl::UTCTimeZone(), time, err);
90 }
91 
92 // If the input string does not contain an explicit UTC offset, interpret
93 // the fields with respect to the given TimeZone.
94 bool ParseTime(const std::string& format, const std::string& input,
95  absl::TimeZone tz, absl::Time* time, std::string* err) {
96  const char* data = input.c_str();
97  while (std::isspace(*data)) ++data;
98 
99  size_t inf_size = strlen(kInfiniteFutureStr);
100  if (strncmp(data, kInfiniteFutureStr, inf_size) == 0) {
101  const char* new_data = data + inf_size;
102  while (std::isspace(*new_data)) ++new_data;
103  if (*new_data == '\0') {
104  *time = InfiniteFuture();
105  return true;
106  }
107  }
108 
109  inf_size = strlen(kInfinitePastStr);
110  if (strncmp(data, kInfinitePastStr, inf_size) == 0) {
111  const char* new_data = data + inf_size;
112  while (std::isspace(*new_data)) ++new_data;
113  if (*new_data == '\0') {
114  *time = InfinitePast();
115  return true;
116  }
117  }
118 
119  std::string error;
120  cctz_parts parts;
121  const bool b = cctz::detail::parse(format, input, cctz::time_zone(tz),
122  &parts.sec, &parts.fem, &error);
123  if (b) {
124  *time = Join(parts);
125  } else if (err != nullptr) {
126  *err = error;
127  }
128  return b;
129 }
130 
131 // Functions required to support absl::Time flags.
132 bool ParseFlag(const std::string& text, absl::Time* t, std::string* error) {
133  return absl::ParseTime(RFC3339_full, text, absl::UTCTimeZone(), t, error);
134 }
135 
136 std::string UnparseFlag(absl::Time t) {
137  return absl::FormatTime(RFC3339_full, t, absl::UTCTimeZone());
138 }
139 
140 } // namespace absl
const char RFC1123_no_wday[]
Definition: time.h:1192
constexpr Time InfiniteFuture()
Definition: time.h:701
std::string FormatTime(const std::string &format, absl::Time t, absl::TimeZone tz)
Definition: format.cc:70
constexpr Duration ToUnixDuration(Time t)
Definition: time.h:1369
std::string UnparseFlag(const T &v)
Definition: marshalling.h:254
const char RFC3339_full[]
Definition: time.h:1184
bool ParseTime(const std::string &format, const std::string &input, absl::Time *time, std::string *err)
Definition: format.cc:87
std::chrono::duration< std::int_fast64_t, std::femto > femtoseconds
Definition: time_zone.h:279
TimeZone UTCTimeZone()
Definition: time.h:1026
constexpr Time FromUnixDuration(Duration d)
Definition: time.h:1368
std::chrono::duration< std::int_fast64_t > seconds
Definition: time_zone.h:37
Definition: algorithm.h:29
cctz::time_point< cctz::seconds > sec
Definition: format.cc:38
const char RFC3339_sec[]
Definition: time.h:1185
static char data[kDataSize]
Definition: city_test.cc:31
std::string format(const std::string &, const time_point< seconds > &, const femtoseconds &, const time_zone &)
constexpr Duration MakeDuration(int64_t hi, uint32_t lo)
Definition: time.h:1313
bool parse(const std::string &, const std::string &, const time_zone &, time_point< seconds > *, femtoseconds *, std::string *err=nullptr)
std::chrono::time_point< std::chrono::system_clock, D > time_point
Definition: time_zone.h:36
constexpr uint32_t GetRepLo(Duration d)
Definition: time.h:1344
bool ParseFlag(absl::string_view input, T *dst, std::string *error)
Definition: marshalling.h:240
const char RFC1123_full[]
Definition: time.h:1191
constexpr int64_t GetRepHi(Duration d)
Definition: time.h:1343
uint64_t b
Definition: layout_test.cc:50
cctz::detail::femtoseconds fem
Definition: format.cc:39
TimeZone LocalTimeZone()
Definition: time.h:1036
constexpr Time InfinitePast()
Definition: time.h:709


abseil_cpp
Author(s):
autogenerated on Mon Feb 28 2022 21:31:18