00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_
00016 #define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_
00017
00018 #include <cstdint>
00019 #include <limits>
00020 #include <ostream>
00021 #include <type_traits>
00022
00023
00024 #if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
00025 #define CONSTEXPR_D constexpr // data
00026 #define CONSTEXPR_F constexpr // function
00027 #define CONSTEXPR_M constexpr // member
00028 #else
00029 #define CONSTEXPR_D const
00030 #define CONSTEXPR_F inline
00031 #define CONSTEXPR_M
00032 #endif
00033
00034 namespace absl {
00035 namespace time_internal {
00036 namespace cctz {
00037
00038
00039 using year_t = std::int_fast64_t;
00040
00041
00042
00043 using diff_t = std::int_fast64_t;
00044
00045 namespace detail {
00046
00047
00048 using month_t = std::int_fast8_t;
00049 using day_t = std::int_fast8_t;
00050 using hour_t = std::int_fast8_t;
00051 using minute_t = std::int_fast8_t;
00052 using second_t = std::int_fast8_t;
00053
00054
00055 struct fields {
00056 CONSTEXPR_M fields(year_t year, month_t month, day_t day,
00057 hour_t hour, minute_t minute, second_t second)
00058 : y(year), m(month), d(day), hh(hour), mm(minute), ss(second) {}
00059 std::int_least64_t y;
00060 std::int_least8_t m;
00061 std::int_least8_t d;
00062 std::int_least8_t hh;
00063 std::int_least8_t mm;
00064 std::int_least8_t ss;
00065 };
00066
00067 struct second_tag {};
00068 struct minute_tag : second_tag {};
00069 struct hour_tag : minute_tag {};
00070 struct day_tag : hour_tag {};
00071 struct month_tag : day_tag {};
00072 struct year_tag : month_tag {};
00073
00075
00076
00077
00078 namespace impl {
00079
00080 CONSTEXPR_F bool is_leap_year(year_t y) noexcept {
00081 return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
00082 }
00083 CONSTEXPR_F int year_index(year_t y, month_t m) noexcept {
00084 return (static_cast<int>((y + (m > 2)) % 400) + 400) % 400;
00085 }
00086 CONSTEXPR_F int days_per_century(year_t y, month_t m) noexcept {
00087 const int yi = year_index(y, m);
00088 return 36524 + (yi == 0 || yi > 300);
00089 }
00090 CONSTEXPR_F int days_per_4years(year_t y, month_t m) noexcept {
00091 const int yi = year_index(y, m);
00092 return 1460 + (yi == 0 || yi > 300 || (yi - 1) % 100 < 96);
00093 }
00094 CONSTEXPR_F int days_per_year(year_t y, month_t m) noexcept {
00095 return is_leap_year(y + (m > 2)) ? 366 : 365;
00096 }
00097 CONSTEXPR_F int days_per_month(year_t y, month_t m) noexcept {
00098 CONSTEXPR_D int k_days_per_month[1 + 12] = {
00099 -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
00100 };
00101 return k_days_per_month[m] + (m == 2 && is_leap_year(y));
00102 }
00103
00104 CONSTEXPR_F fields n_day(year_t y, month_t m, diff_t d, diff_t cd,
00105 hour_t hh, minute_t mm, second_t ss) noexcept {
00106 y += (cd / 146097) * 400;
00107 cd %= 146097;
00108 if (cd < 0) {
00109 y -= 400;
00110 cd += 146097;
00111 }
00112 y += (d / 146097) * 400;
00113 d = d % 146097 + cd;
00114 if (d > 0) {
00115 if (d > 146097) {
00116 y += 400;
00117 d -= 146097;
00118 }
00119 } else {
00120 if (d > -365) {
00121
00122
00123 y -= 1;
00124 d += days_per_year(y, m);
00125 } else {
00126 y -= 400;
00127 d += 146097;
00128 }
00129 }
00130 if (d > 365) {
00131 for (int n = days_per_century(y, m); d > n; n = days_per_century(y, m)) {
00132 d -= n;
00133 y += 100;
00134 }
00135 for (int n = days_per_4years(y, m); d > n; n = days_per_4years(y, m)) {
00136 d -= n;
00137 y += 4;
00138 }
00139 for (int n = days_per_year(y, m); d > n; n = days_per_year(y, m)) {
00140 d -= n;
00141 ++y;
00142 }
00143 }
00144 if (d > 28) {
00145 for (int n = days_per_month(y, m); d > n; n = days_per_month(y, m)) {
00146 d -= n;
00147 if (++m > 12) {
00148 ++y;
00149 m = 1;
00150 }
00151 }
00152 }
00153 return fields(y, m, static_cast<day_t>(d), hh, mm, ss);
00154 }
00155 CONSTEXPR_F fields n_mon(year_t y, diff_t m, diff_t d, diff_t cd,
00156 hour_t hh, minute_t mm, second_t ss) noexcept {
00157 if (m != 12) {
00158 y += m / 12;
00159 m %= 12;
00160 if (m <= 0) {
00161 y -= 1;
00162 m += 12;
00163 }
00164 }
00165 return n_day(y, static_cast<month_t>(m), d, cd, hh, mm, ss);
00166 }
00167 CONSTEXPR_F fields n_hour(year_t y, diff_t m, diff_t d, diff_t cd,
00168 diff_t hh, minute_t mm, second_t ss) noexcept {
00169 cd += hh / 24;
00170 hh %= 24;
00171 if (hh < 0) {
00172 cd -= 1;
00173 hh += 24;
00174 }
00175 return n_mon(y, m, d, cd, static_cast<hour_t>(hh), mm, ss);
00176 }
00177 CONSTEXPR_F fields n_min(year_t y, diff_t m, diff_t d, diff_t hh, diff_t ch,
00178 diff_t mm, second_t ss) noexcept {
00179 ch += mm / 60;
00180 mm %= 60;
00181 if (mm < 0) {
00182 ch -= 1;
00183 mm += 60;
00184 }
00185 return n_hour(y, m, d, hh / 24 + ch / 24, hh % 24 + ch % 24,
00186 static_cast<minute_t>(mm), ss);
00187 }
00188 CONSTEXPR_F fields n_sec(year_t y, diff_t m, diff_t d, diff_t hh, diff_t mm,
00189 diff_t ss) noexcept {
00190
00191 if (0 <= ss && ss < 60) {
00192 const second_t nss = static_cast<second_t>(ss);
00193 if (0 <= mm && mm < 60) {
00194 const minute_t nmm = static_cast<minute_t>(mm);
00195 if (0 <= hh && hh < 24) {
00196 const hour_t nhh = static_cast<hour_t>(hh);
00197 if (1 <= d && d <= 28 && 1 <= m && m <= 12) {
00198 const day_t nd = static_cast<day_t>(d);
00199 const month_t nm = static_cast<month_t>(m);
00200 return fields(y, nm, nd, nhh, nmm, nss);
00201 }
00202 return n_mon(y, m, d, 0, nhh, nmm, nss);
00203 }
00204 return n_hour(y, m, d, hh / 24, hh % 24, nmm, nss);
00205 }
00206 return n_min(y, m, d, hh, mm / 60, mm % 60, nss);
00207 }
00208 diff_t cm = ss / 60;
00209 ss %= 60;
00210 if (ss < 0) {
00211 cm -= 1;
00212 ss += 60;
00213 }
00214 return n_min(y, m, d, hh, mm / 60 + cm / 60, mm % 60 + cm % 60,
00215 static_cast<second_t>(ss));
00216 }
00217
00218 }
00219
00221
00222
00223 CONSTEXPR_F fields step(second_tag, fields f, diff_t n) noexcept {
00224 return impl::n_sec(f.y, f.m, f.d, f.hh, f.mm + n / 60, f.ss + n % 60);
00225 }
00226 CONSTEXPR_F fields step(minute_tag, fields f, diff_t n) noexcept {
00227 return impl::n_min(f.y, f.m, f.d, f.hh + n / 60, 0, f.mm + n % 60, f.ss);
00228 }
00229 CONSTEXPR_F fields step(hour_tag, fields f, diff_t n) noexcept {
00230 return impl::n_hour(f.y, f.m, f.d + n / 24, 0, f.hh + n % 24, f.mm, f.ss);
00231 }
00232 CONSTEXPR_F fields step(day_tag, fields f, diff_t n) noexcept {
00233 return impl::n_day(f.y, f.m, f.d, n, f.hh, f.mm, f.ss);
00234 }
00235 CONSTEXPR_F fields step(month_tag, fields f, diff_t n) noexcept {
00236 return impl::n_mon(f.y + n / 12, f.m + n % 12, f.d, 0, f.hh, f.mm, f.ss);
00237 }
00238 CONSTEXPR_F fields step(year_tag, fields f, diff_t n) noexcept {
00239 return fields(f.y + n, f.m, f.d, f.hh, f.mm, f.ss);
00240 }
00241
00243
00244 namespace impl {
00245
00246
00247 CONSTEXPR_F diff_t scale_add(diff_t v, diff_t f, diff_t a) noexcept {
00248 return (v < 0) ? ((v + 1) * f + a) - f : ((v - 1) * f + a) + f;
00249 }
00250
00251
00252
00253 CONSTEXPR_F diff_t ymd_ord(year_t y, month_t m, day_t d) noexcept {
00254 const diff_t eyear = (m <= 2) ? y - 1 : y;
00255 const diff_t era = (eyear >= 0 ? eyear : eyear - 399) / 400;
00256 const diff_t yoe = eyear - era * 400;
00257 const diff_t doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1;
00258 const diff_t doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
00259 return era * 146097 + doe - 719468;
00260 }
00261
00262
00263
00264
00265
00266
00267 CONSTEXPR_F diff_t day_difference(year_t y1, month_t m1, day_t d1,
00268 year_t y2, month_t m2, day_t d2) noexcept {
00269 const diff_t a_c4_off = y1 % 400;
00270 const diff_t b_c4_off = y2 % 400;
00271 diff_t c4_diff = (y1 - a_c4_off) - (y2 - b_c4_off);
00272 diff_t delta = ymd_ord(a_c4_off, m1, d1) - ymd_ord(b_c4_off, m2, d2);
00273 if (c4_diff > 0 && delta < 0) {
00274 delta += 2 * 146097;
00275 c4_diff -= 2 * 400;
00276 } else if (c4_diff < 0 && delta > 0) {
00277 delta -= 2 * 146097;
00278 c4_diff += 2 * 400;
00279 }
00280 return (c4_diff / 400 * 146097) + delta;
00281 }
00282
00283 }
00284
00285
00286 CONSTEXPR_F diff_t difference(year_tag, fields f1, fields f2) noexcept {
00287 return f1.y - f2.y;
00288 }
00289 CONSTEXPR_F diff_t difference(month_tag, fields f1, fields f2) noexcept {
00290 return impl::scale_add(difference(year_tag{}, f1, f2), 12, (f1.m - f2.m));
00291 }
00292 CONSTEXPR_F diff_t difference(day_tag, fields f1, fields f2) noexcept {
00293 return impl::day_difference(f1.y, f1.m, f1.d, f2.y, f2.m, f2.d);
00294 }
00295 CONSTEXPR_F diff_t difference(hour_tag, fields f1, fields f2) noexcept {
00296 return impl::scale_add(difference(day_tag{}, f1, f2), 24, (f1.hh - f2.hh));
00297 }
00298 CONSTEXPR_F diff_t difference(minute_tag, fields f1, fields f2) noexcept {
00299 return impl::scale_add(difference(hour_tag{}, f1, f2), 60, (f1.mm - f2.mm));
00300 }
00301 CONSTEXPR_F diff_t difference(second_tag, fields f1, fields f2) noexcept {
00302 return impl::scale_add(difference(minute_tag{}, f1, f2), 60, f1.ss - f2.ss);
00303 }
00304
00306
00307
00308 CONSTEXPR_F fields align(second_tag, fields f) noexcept {
00309 return f;
00310 }
00311 CONSTEXPR_F fields align(minute_tag, fields f) noexcept {
00312 return fields{f.y, f.m, f.d, f.hh, f.mm, 0};
00313 }
00314 CONSTEXPR_F fields align(hour_tag, fields f) noexcept {
00315 return fields{f.y, f.m, f.d, f.hh, 0, 0};
00316 }
00317 CONSTEXPR_F fields align(day_tag, fields f) noexcept {
00318 return fields{f.y, f.m, f.d, 0, 0, 0};
00319 }
00320 CONSTEXPR_F fields align(month_tag, fields f) noexcept {
00321 return fields{f.y, f.m, 1, 0, 0, 0};
00322 }
00323 CONSTEXPR_F fields align(year_tag, fields f) noexcept {
00324 return fields{f.y, 1, 1, 0, 0, 0};
00325 }
00326
00328
00329 namespace impl {
00330
00331 template <typename H>
00332 H AbslHashValueImpl(second_tag, H h, fields f) {
00333 return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm, f.ss);
00334 }
00335 template <typename H>
00336 H AbslHashValueImpl(minute_tag, H h, fields f) {
00337 return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm);
00338 }
00339 template <typename H>
00340 H AbslHashValueImpl(hour_tag, H h, fields f) {
00341 return H::combine(std::move(h), f.y, f.m, f.d, f.hh);
00342 }
00343 template <typename H>
00344 H AbslHashValueImpl(day_tag, H h, fields f) {
00345 return H::combine(std::move(h), f.y, f.m, f.d);
00346 }
00347 template <typename H>
00348 H AbslHashValueImpl(month_tag, H h, fields f) {
00349 return H::combine(std::move(h), f.y, f.m);
00350 }
00351 template <typename H>
00352 H AbslHashValueImpl(year_tag, H h, fields f) {
00353 return H::combine(std::move(h), f.y);
00354 }
00355
00356 }
00357
00359
00360 template <typename T>
00361 class civil_time {
00362 public:
00363 explicit CONSTEXPR_M civil_time(year_t y, diff_t m = 1, diff_t d = 1,
00364 diff_t hh = 0, diff_t mm = 0,
00365 diff_t ss = 0) noexcept
00366 : civil_time(impl::n_sec(y, m, d, hh, mm, ss)) {}
00367
00368 CONSTEXPR_M civil_time() noexcept : f_{1970, 1, 1, 0, 0, 0} {}
00369 civil_time(const civil_time&) = default;
00370 civil_time& operator=(const civil_time&) = default;
00371
00372
00373
00374
00375
00376 template <typename U, typename S>
00377 using preserves_data =
00378 typename std::enable_if<std::is_base_of<U, S>::value>::type;
00379 template <typename U>
00380 CONSTEXPR_M civil_time(const civil_time<U>& ct,
00381 preserves_data<T, U>* = nullptr) noexcept
00382 : civil_time(ct.f_) {}
00383 template <typename U>
00384 explicit CONSTEXPR_M civil_time(const civil_time<U>& ct,
00385 preserves_data<U, T>* = nullptr) noexcept
00386 : civil_time(ct.f_) {}
00387
00388
00389 static CONSTEXPR_F civil_time (max)() {
00390 const auto max_year = (std::numeric_limits<std::int_least64_t>::max)();
00391 return civil_time(max_year, 12, 31, 23, 59, 59);
00392 }
00393 static CONSTEXPR_F civil_time (min)() {
00394 const auto min_year = (std::numeric_limits<std::int_least64_t>::min)();
00395 return civil_time(min_year, 1, 1, 0, 0, 0);
00396 }
00397
00398
00399 CONSTEXPR_M year_t year() const noexcept { return f_.y; }
00400 CONSTEXPR_M int month() const noexcept { return f_.m; }
00401 CONSTEXPR_M int day() const noexcept { return f_.d; }
00402 CONSTEXPR_M int hour() const noexcept { return f_.hh; }
00403 CONSTEXPR_M int minute() const noexcept { return f_.mm; }
00404 CONSTEXPR_M int second() const noexcept { return f_.ss; }
00405
00406
00407 CONSTEXPR_M civil_time& operator+=(diff_t n) noexcept {
00408 f_ = step(T{}, f_, n);
00409 return *this;
00410 }
00411 CONSTEXPR_M civil_time& operator-=(diff_t n) noexcept {
00412 if (n != (std::numeric_limits<diff_t>::min)()) {
00413 f_ = step(T{}, f_, -n);
00414 } else {
00415 f_ = step(T{}, step(T{}, f_, -(n + 1)), 1);
00416 }
00417 return *this;
00418 }
00419 CONSTEXPR_M civil_time& operator++() noexcept {
00420 return *this += 1;
00421 }
00422 CONSTEXPR_M civil_time operator++(int) noexcept {
00423 const civil_time a = *this;
00424 ++*this;
00425 return a;
00426 }
00427 CONSTEXPR_M civil_time& operator--() noexcept {
00428 return *this -= 1;
00429 }
00430 CONSTEXPR_M civil_time operator--(int) noexcept {
00431 const civil_time a = *this;
00432 --*this;
00433 return a;
00434 }
00435
00436
00437 friend CONSTEXPR_F civil_time operator+(civil_time a, diff_t n) noexcept {
00438 return a += n;
00439 }
00440 friend CONSTEXPR_F civil_time operator+(diff_t n, civil_time a) noexcept {
00441 return a += n;
00442 }
00443 friend CONSTEXPR_F civil_time operator-(civil_time a, diff_t n) noexcept {
00444 return a -= n;
00445 }
00446 friend CONSTEXPR_F diff_t operator-(civil_time lhs, civil_time rhs) noexcept {
00447 return difference(T{}, lhs.f_, rhs.f_);
00448 }
00449
00450 template <typename H>
00451 friend H AbslHashValue(H h, civil_time a) {
00452 return impl::AbslHashValueImpl(T{}, std::move(h), a.f_);
00453 }
00454
00455 private:
00456
00457
00458 template <typename U>
00459 friend class civil_time;
00460
00461
00462 explicit CONSTEXPR_M civil_time(fields f) noexcept : f_(align(T{}, f)) {}
00463
00464 fields f_;
00465 };
00466
00467
00468
00469 template <typename T, typename U>
00470 CONSTEXPR_F diff_t operator-(civil_time<T>, civil_time<U>) = delete;
00471
00472 using civil_year = civil_time<year_tag>;
00473 using civil_month = civil_time<month_tag>;
00474 using civil_day = civil_time<day_tag>;
00475 using civil_hour = civil_time<hour_tag>;
00476 using civil_minute = civil_time<minute_tag>;
00477 using civil_second = civil_time<second_tag>;
00478
00480
00481
00482
00483 template <typename T1, typename T2>
00484 CONSTEXPR_F bool operator<(const civil_time<T1>& lhs,
00485 const civil_time<T2>& rhs) noexcept {
00486 return (lhs.year() < rhs.year() ||
00487 (lhs.year() == rhs.year() &&
00488 (lhs.month() < rhs.month() ||
00489 (lhs.month() == rhs.month() &&
00490 (lhs.day() < rhs.day() ||
00491 (lhs.day() == rhs.day() &&
00492 (lhs.hour() < rhs.hour() ||
00493 (lhs.hour() == rhs.hour() &&
00494 (lhs.minute() < rhs.minute() ||
00495 (lhs.minute() == rhs.minute() &&
00496 (lhs.second() < rhs.second())))))))))));
00497 }
00498 template <typename T1, typename T2>
00499 CONSTEXPR_F bool operator<=(const civil_time<T1>& lhs,
00500 const civil_time<T2>& rhs) noexcept {
00501 return !(rhs < lhs);
00502 }
00503 template <typename T1, typename T2>
00504 CONSTEXPR_F bool operator>=(const civil_time<T1>& lhs,
00505 const civil_time<T2>& rhs) noexcept {
00506 return !(lhs < rhs);
00507 }
00508 template <typename T1, typename T2>
00509 CONSTEXPR_F bool operator>(const civil_time<T1>& lhs,
00510 const civil_time<T2>& rhs) noexcept {
00511 return rhs < lhs;
00512 }
00513 template <typename T1, typename T2>
00514 CONSTEXPR_F bool operator==(const civil_time<T1>& lhs,
00515 const civil_time<T2>& rhs) noexcept {
00516 return lhs.year() == rhs.year() && lhs.month() == rhs.month() &&
00517 lhs.day() == rhs.day() && lhs.hour() == rhs.hour() &&
00518 lhs.minute() == rhs.minute() && lhs.second() == rhs.second();
00519 }
00520 template <typename T1, typename T2>
00521 CONSTEXPR_F bool operator!=(const civil_time<T1>& lhs,
00522 const civil_time<T2>& rhs) noexcept {
00523 return !(lhs == rhs);
00524 }
00525
00527
00528 enum class weekday {
00529 monday,
00530 tuesday,
00531 wednesday,
00532 thursday,
00533 friday,
00534 saturday,
00535 sunday,
00536 };
00537
00538 CONSTEXPR_F weekday get_weekday(const civil_day& cd) noexcept {
00539 CONSTEXPR_D weekday k_weekday_by_mon_off[13] = {
00540 weekday::monday, weekday::tuesday, weekday::wednesday,
00541 weekday::thursday, weekday::friday, weekday::saturday,
00542 weekday::sunday, weekday::monday, weekday::tuesday,
00543 weekday::wednesday, weekday::thursday, weekday::friday,
00544 weekday::saturday,
00545 };
00546 CONSTEXPR_D int k_weekday_offsets[1 + 12] = {
00547 -1, 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4,
00548 };
00549 year_t wd = 2400 + (cd.year() % 400) - (cd.month() < 3);
00550 wd += wd / 4 - wd / 100 + wd / 400;
00551 wd += k_weekday_offsets[cd.month()] + cd.day();
00552 return k_weekday_by_mon_off[wd % 7 + 6];
00553 }
00554
00556
00557 CONSTEXPR_F civil_day next_weekday(civil_day cd, weekday wd) noexcept {
00558 CONSTEXPR_D weekday k_weekdays_forw[14] = {
00559 weekday::monday, weekday::tuesday, weekday::wednesday,
00560 weekday::thursday, weekday::friday, weekday::saturday,
00561 weekday::sunday, weekday::monday, weekday::tuesday,
00562 weekday::wednesday, weekday::thursday, weekday::friday,
00563 weekday::saturday, weekday::sunday,
00564 };
00565 weekday base = get_weekday(cd);
00566 for (int i = 0;; ++i) {
00567 if (base == k_weekdays_forw[i]) {
00568 for (int j = i + 1;; ++j) {
00569 if (wd == k_weekdays_forw[j]) {
00570 return cd + (j - i);
00571 }
00572 }
00573 }
00574 }
00575 }
00576
00577 CONSTEXPR_F civil_day prev_weekday(civil_day cd, weekday wd) noexcept {
00578 CONSTEXPR_D weekday k_weekdays_back[14] = {
00579 weekday::sunday, weekday::saturday, weekday::friday,
00580 weekday::thursday, weekday::wednesday, weekday::tuesday,
00581 weekday::monday, weekday::sunday, weekday::saturday,
00582 weekday::friday, weekday::thursday, weekday::wednesday,
00583 weekday::tuesday, weekday::monday,
00584 };
00585 weekday base = get_weekday(cd);
00586 for (int i = 0;; ++i) {
00587 if (base == k_weekdays_back[i]) {
00588 for (int j = i + 1;; ++j) {
00589 if (wd == k_weekdays_back[j]) {
00590 return cd - (j - i);
00591 }
00592 }
00593 }
00594 }
00595 }
00596
00597 CONSTEXPR_F int get_yearday(const civil_day& cd) noexcept {
00598 CONSTEXPR_D int k_month_offsets[1 + 12] = {
00599 -1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
00600 };
00601 const int feb29 = (cd.month() > 2 && impl::is_leap_year(cd.year()));
00602 return k_month_offsets[cd.month()] + feb29 + cd.day();
00603 }
00604
00606
00607 std::ostream& operator<<(std::ostream& os, const civil_year& y);
00608 std::ostream& operator<<(std::ostream& os, const civil_month& m);
00609 std::ostream& operator<<(std::ostream& os, const civil_day& d);
00610 std::ostream& operator<<(std::ostream& os, const civil_hour& h);
00611 std::ostream& operator<<(std::ostream& os, const civil_minute& m);
00612 std::ostream& operator<<(std::ostream& os, const civil_second& s);
00613 std::ostream& operator<<(std::ostream& os, weekday wd);
00614
00615 }
00616 }
00617 }
00618 }
00619
00620 #undef CONSTEXPR_M
00621 #undef CONSTEXPR_F
00622 #undef CONSTEXPR_D
00623
00624 #endif // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_DETAIL_H_