Add streaming inserter for utc_time.

* Fix bug in utc_to_sys.
This commit is contained in:
Howard Hinnant
2016-06-06 21:05:43 -04:00
parent 3e0848bd04
commit f44e692540
2 changed files with 42 additions and 6 deletions

2
date.h
View File

@@ -3628,6 +3628,7 @@ public:
CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;}
CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} 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 std::chrono::seconds seconds() const NOEXCEPT {return s_;}
CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;}
@@ -3708,6 +3709,7 @@ public:
CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;}
CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} 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 std::chrono::seconds seconds() const NOEXCEPT {return s_;}
CONSTCD11 precision subseconds() const NOEXCEPT {return sub_s_;} CONSTCD11 precision subseconds() const NOEXCEPT {return sub_s_;}
CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;}

46
tz.h
View File

@@ -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. Technically any OS may use the mapping process but currently only Windows does use it.
*/ */
#include <iostream>
#ifdef _WIN32 #ifdef _WIN32
#ifndef TIMEZONE_MAPPING #ifndef TIMEZONE_MAPPING
#define TIMEZONE_MAPPING 1 #define TIMEZONE_MAPPING 1
@@ -1058,10 +1056,18 @@ utc_clock::utc_to_sys(utc_time<Duration> t)
using duration = typename std::common_type<Duration, seconds>::type; using duration = typename std::common_type<Duration, seconds>::type;
auto const& leaps = get_tzdb().leaps; auto const& leaps = get_tzdb().leaps;
auto tp = sys_time<duration>{t.time_since_epoch()}; auto tp = sys_time<duration>{t.time_since_epoch()};
auto const lt = std::upper_bound(leaps.begin(), leaps.end(), tp); if (tp >= leaps.front())
tp -= seconds{lt-leaps.begin()}; {
if (lt != leaps.begin() && tp + seconds{1} < lt[-1]) auto const lt = std::upper_bound(leaps.begin(), leaps.end(), tp);
tp += seconds{1}; 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; return tp;
} }
@@ -1081,6 +1087,34 @@ to_utc_time(sys_time<Duration> st)
return utc_clock::sys_to_utc(st); return utc_clock::sys_to_utc(st);
} }
template <class CharT, class Traits, class Duration>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os, const utc_time<Duration>& t)
{
using namespace std::chrono;
using duration = typename std::common_type<Duration, seconds>::type;
auto const& leaps = get_tzdb().leaps;
auto tp = sys_time<duration>{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<days>(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 // format
namespace detail namespace detail