diff --git a/include/date/tz.h b/include/date/tz.h index 4159c1c..2befd92 100644 --- a/include/date/tz.h +++ b/include/date/tz.h @@ -1865,6 +1865,16 @@ public: static std::chrono::time_point::type> from_sys(const std::chrono::time_point&); + + template + static + std::chrono::time_point::type> + to_local(const std::chrono::time_point&); + + template + static + std::chrono::time_point::type> + from_local(const std::chrono::time_point&); }; template @@ -1933,6 +1943,21 @@ utc_clock::now() return from_sys(system_clock::now()); } +template +utc_time::type> +utc_clock::from_local(const local_time& st) +{ + return from_sys(sys_time{st.time_since_epoch()}); +} + +template +local_time::type> +utc_clock::to_local(const utc_time& ut) +{ + using duration = typename std::common_type::type; + return local_time{to_sys(ut).time_since_epoch()}; +} + template std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, @@ -2017,6 +2042,16 @@ public: static std::chrono::time_point::type> from_utc(const std::chrono::time_point&) NOEXCEPT; + + template + static + std::chrono::time_point::type> + to_local(const std::chrono::time_point&) NOEXCEPT; + + template + static + std::chrono::time_point::type> + from_local(const std::chrono::time_point&) NOEXCEPT; }; template @@ -2054,23 +2089,34 @@ tai_clock::now() return from_utc(utc_clock::now()); } +template +inline +local_time::type> +tai_clock::to_local(const tai_time& t) NOEXCEPT +{ + using duration = typename std::common_type::type; + return local_time{t.time_since_epoch()} - + (local_days(year{1970}/jan/1) - local_days(year{1958}/jan/1)); +} + +template +inline +tai_time::type> +tai_clock::from_local(const local_time& t) NOEXCEPT +{ + using duration = typename std::common_type::type; + return tai_time{t.time_since_epoch()} + + (local_days(year{1970}/jan/1) - local_days(year{1958}/jan/1)); +} + template std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const tai_time& t) { - using namespace std; - using namespace std::chrono; - using CT = typename common_type::type; - const string abbrev("TAI"); - CONSTDATA seconds offset{0}; - auto tp = sys_time{t.time_since_epoch()} - - seconds(sys_days(year{1970}/January/1) - sys_days(year{1958}/January/1)); - auto const sd = floor(tp); - year_month_day ymd = sd; - auto time = make_time(tp - sys_seconds{sd}); - fields fds{ymd, time}; - return to_stream(os, fmt, fds, &abbrev, &offset); + const std::string abbrev("TAI"); + CONSTDATA std::chrono::seconds offset{0}; + return to_stream(os, fmt, tai_clock::to_local(t), &abbrev, &offset); } template @@ -2088,21 +2134,10 @@ from_stream(std::basic_istream& is, const CharT* fmt, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { - using namespace std; - using namespace std::chrono; - using CT = typename common_type::type; - minutes offset_local{}; - auto offptr = offset ? offset : &offset_local; - fields fds{}; - fds.has_tod = true; - from_stream(is, fmt, fds, abbrev, offptr); - if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) - is.setstate(ios::failbit); + local_time lp; + from_stream(is, fmt, lp, abbrev, offset); if (!is.fail()) - tp = tai_time{duration_cast( - (sys_days(fds.ymd) + - (sys_days(year{1970}/January/1) - sys_days(year{1958}/January/1)) - - *offptr + fds.tod.to_duration()).time_since_epoch())}; + tp = tai_clock::from_local(lp); return is; } @@ -2129,6 +2164,15 @@ public: std::chrono::time_point::type> from_utc(const std::chrono::time_point&) NOEXCEPT; + template + static + std::chrono::time_point::type> + to_local(const std::chrono::time_point&) NOEXCEPT; + + template + static + std::chrono::time_point::type> + from_local(const std::chrono::time_point&) NOEXCEPT; }; template @@ -2168,23 +2212,35 @@ gps_clock::now() return from_utc(utc_clock::now()); } +template +inline +local_time::type> +gps_clock::to_local(const gps_time& t) NOEXCEPT +{ + using duration = typename std::common_type::type; + return local_time{t.time_since_epoch()} + + (local_days(year{1980}/jan/sun[1]) - local_days(year{1970}/jan/1)); +} + +template +inline +gps_time::type> +gps_clock::from_local(const local_time& t) NOEXCEPT +{ + using duration = typename std::common_type::type; + return gps_time{t.time_since_epoch()} - + (local_days(year{1980}/jan/sun[1]) - local_days(year{1970}/jan/1)); +} + + template std::basic_ostream& to_stream(std::basic_ostream& os, const CharT* fmt, const gps_time& t) { - using namespace std; - using namespace std::chrono; - using CT = typename common_type::type; - const string abbrev("GPS"); - CONSTDATA seconds offset{0}; - auto tp = sys_time{t.time_since_epoch()} + - seconds(sys_days(year{1980}/January/Sunday[1]) - sys_days(year{1970}/January/1)); - auto const sd = floor(tp); - year_month_day ymd = sd; - auto time = make_time(tp - sys_seconds{sd}); - fields fds{ymd, time}; - return to_stream(os, fmt, fds, &abbrev, &offset); + const std::string abbrev("GPS"); + CONSTDATA std::chrono::seconds offset{0}; + return to_stream(os, fmt, gps_clock::to_local(t), &abbrev, &offset); } template @@ -2202,21 +2258,10 @@ from_stream(std::basic_istream& is, const CharT* fmt, std::basic_string* abbrev = nullptr, std::chrono::minutes* offset = nullptr) { - using namespace std; - using namespace std::chrono; - using CT = typename common_type::type; - minutes offset_local{}; - auto offptr = offset ? offset : &offset_local; - fields fds{}; - fds.has_tod = true; - from_stream(is, fmt, fds, abbrev, offptr); - if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) - is.setstate(ios::failbit); + local_time lp; + from_stream(is, fmt, lp, abbrev, offset); if (!is.fail()) - tp = gps_time{duration_cast( - (sys_days(fds.ymd) - - (sys_days(year{1980}/January/Sunday[1]) - sys_days(year{1970}/January/1)) - - *offptr + fds.tod.to_duration()).time_since_epoch())}; + tp = gps_clock::from_local(lp); return is; }