From f44e6925402f1acfe5fdc7e81a77e5410d019663 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Mon, 6 Jun 2016 21:05:43 -0400 Subject: [PATCH] Add streaming inserter for utc_time. * Fix bug in utc_to_sys. --- date.h | 2 ++ tz.h | 46 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/date.h b/date.h index e5477ef..c21524e 100644 --- a/date.h +++ b/date.h @@ -3628,6 +3628,7 @@ public: CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} + CONSTCD11 std::chrono::seconds& seconds() NOEXCEPT {return s_;} CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_;} CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} @@ -3708,6 +3709,7 @@ public: CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} + CONSTCD11 std::chrono::seconds& seconds() NOEXCEPT {return s_;} CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_;} CONSTCD11 precision subseconds() const NOEXCEPT {return sub_s_;} CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} diff --git a/tz.h b/tz.h index 254a68d..09c7a0f 100644 --- a/tz.h +++ b/tz.h @@ -48,8 +48,6 @@ On Windows, the names are never "Standard" so mapping is always required. Technically any OS may use the mapping process but currently only Windows does use it. */ -#include - #ifdef _WIN32 #ifndef TIMEZONE_MAPPING #define TIMEZONE_MAPPING 1 @@ -1058,10 +1056,18 @@ utc_clock::utc_to_sys(utc_time t) using duration = typename std::common_type::type; auto const& leaps = get_tzdb().leaps; auto tp = sys_time{t.time_since_epoch()}; - auto const lt = std::upper_bound(leaps.begin(), leaps.end(), tp); - tp -= seconds{lt-leaps.begin()}; - if (lt != leaps.begin() && tp + seconds{1} < lt[-1]) - tp += seconds{1}; + if (tp >= leaps.front()) + { + auto const lt = std::upper_bound(leaps.begin(), leaps.end(), tp); + tp -= seconds{lt-leaps.begin()}; + if (tp < lt[-1]) + { + if (tp >= lt[-1].date() - seconds{1}) + tp = lt[-1].date() - duration{1}; + else + tp += seconds{1}; + } + } return tp; } @@ -1081,6 +1087,34 @@ to_utc_time(sys_time st) return utc_clock::sys_to_utc(st); } +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const utc_time& t) +{ + using namespace std::chrono; + using duration = typename std::common_type::type; + auto const& leaps = get_tzdb().leaps; + auto tp = sys_time{t.time_since_epoch()}; + if (tp >= leaps.front()) + { + auto const lt = std::upper_bound(leaps.begin(), leaps.end(), tp); + tp -= seconds{lt-leaps.begin()}; + if (tp < lt[-1]) + { + if (tp >= lt[-1].date() - seconds{1}) + { + auto const dp = floor(tp); + auto time = make_time(tp-dp); + time.seconds() += seconds{1}; + return os << year_month_day(dp) << ' ' << time; + } + else + tp += seconds{1}; + } + } + return os << tp; +} + // format namespace detail