From 1e5d2fa8ddef397b2e5470be9c5a8661f5d83415 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Thu, 21 Apr 2016 16:08:06 -0400 Subject: [PATCH] Create local and system time types for timezone functions. * Add sys_time. * Add sys_days. * Add sys_seconds. * Add local_time. * Add local_days. * Add local_seconds. * Rename day_point to sys_days. * Rename Zone to time_zone. --- date.h | 179 +++++-- iso_week.h | 37 +- test/tz_test/tzdata2016d.txt.zip | Bin 0 -> 128096 bytes test/tz_test/validate.cpp | 63 ++- test/tz_test/zone.pass.cpp | 12 +- tz.cpp | 123 +++-- tz.h | 874 ++++++++++++++++++++++--------- tz_private.h | 32 +- 8 files changed, 906 insertions(+), 414 deletions(-) create mode 100644 test/tz_test/tzdata2016d.txt.zip diff --git a/date.h b/date.h index f88e74c..2703dad 100644 --- a/date.h +++ b/date.h @@ -22,17 +22,23 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +// +// Our apologies. When the previous paragraph was written, lowercase had not yet +// been invented (that woud involve another several millennia of evolution). +// We did not mean to shout. #include #include #if !(__cplusplus >= 201402) # include #endif +#include +#include #include #include #include #include -#include +#include namespace date { @@ -81,7 +87,22 @@ using months = std::chrono::duration // time_point -using day_point = std::chrono::time_point; +template + using sys_time = std::chrono::time_point; + +using sys_days = sys_time; +using sys_seconds = sys_time; + +struct local_t {}; + +template + using local_time = std::chrono::time_point; + +using local_seconds = local_time; +using local_days = local_time; + +// deprecated: +using day_point = sys_days; // types @@ -314,7 +335,8 @@ class weekday public: explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT; explicit weekday(int) = delete; - CONSTCD11 weekday(const day_point& dp) NOEXCEPT; + CONSTCD11 weekday(const sys_days& dp) NOEXCEPT; + CONSTCD11 weekday(const local_days& dp) NOEXCEPT; weekday& operator++() NOEXCEPT; weekday operator++(int) NOEXCEPT; @@ -525,7 +547,9 @@ public: CONSTCD11 year_month_day(const date::year& y, const date::month& m, const date::day& d) NOEXCEPT; CONSTCD14 year_month_day(const year_month_day_last& ymdl) NOEXCEPT; - CONSTCD14 year_month_day(const day_point& dp) NOEXCEPT; + + CONSTCD14 year_month_day(sys_days dp) NOEXCEPT; + CONSTCD14 year_month_day(local_days dp) NOEXCEPT; year_month_day& operator+=(const months& m) NOEXCEPT; year_month_day& operator-=(const months& m) NOEXCEPT; @@ -536,11 +560,13 @@ public: CONSTCD11 date::month month() const NOEXCEPT; CONSTCD11 date::day day() const NOEXCEPT; - CONSTCD14 operator day_point() const NOEXCEPT; + CONSTCD14 operator sys_days() const NOEXCEPT; + CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: - static CONSTCD14 year_month_day from_day_point(const day_point& dp) NOEXCEPT; + static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT; + CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT; @@ -580,7 +606,8 @@ public: CONSTCD11 date::month_day_last month_day_last() const NOEXCEPT; CONSTCD14 date::day day() const NOEXCEPT; - CONSTCD14 operator day_point() const NOEXCEPT; + CONSTCD14 operator sys_days() const NOEXCEPT; + CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; @@ -634,7 +661,8 @@ class year_month_weekday public: CONSTCD11 year_month_weekday(const date::year& y, const date::month& m, const date::weekday_indexed& wdi) NOEXCEPT; - CONSTCD14 year_month_weekday(const day_point& dp) NOEXCEPT; + CONSTCD14 year_month_weekday(const sys_days& dp) NOEXCEPT; + CONSTCD14 year_month_weekday(const local_days& dp) NOEXCEPT; year_month_weekday& operator+=(const months& m) NOEXCEPT; year_month_weekday& operator-=(const months& m) NOEXCEPT; @@ -647,11 +675,13 @@ public: CONSTCD11 unsigned index() const NOEXCEPT; CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT; - CONSTCD14 operator day_point() const NOEXCEPT; + CONSTCD14 operator sys_days() const NOEXCEPT; + CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: - static CONSTCD14 year_month_weekday from_day_point(const day_point& dp) NOEXCEPT; + static CONSTCD14 year_month_weekday from_days(days dp) NOEXCEPT; + CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 @@ -707,8 +737,12 @@ public: CONSTCD11 date::weekday weekday() const NOEXCEPT; CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT; - CONSTCD14 operator day_point() const NOEXCEPT; + CONSTCD14 operator sys_days() const NOEXCEPT; + CONSTCD14 explicit operator local_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; + +private: + CONSTCD14 days to_days() const NOEXCEPT; }; CONSTCD11 @@ -1431,7 +1465,13 @@ weekday::weekday(unsigned wd) NOEXCEPT CONSTCD11 inline -weekday::weekday(const day_point& dp) NOEXCEPT +weekday::weekday(const sys_days& dp) NOEXCEPT + : wd_(weekday_from_days(dp.time_since_epoch().count())) + {} + +CONSTCD11 +inline +weekday::weekday(const local_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} @@ -2171,6 +2211,20 @@ year_month_day_last::day() const NOEXCEPT d[static_cast(month()) - 1] : date::day{29}; } +CONSTCD14 +inline +year_month_day_last::operator sys_days() const NOEXCEPT +{ + return sys_days(year()/month()/day()); +} + +CONSTCD14 +inline +year_month_day_last::operator local_days() const NOEXCEPT +{ + return local_days(year()/month()/day()); +} + CONSTCD11 inline bool @@ -2305,8 +2359,14 @@ year_month_day::year_month_day(const year_month_day_last& ymdl) NOEXCEPT CONSTCD14 inline -year_month_day::year_month_day(const day_point& dp) NOEXCEPT - : year_month_day(from_day_point(dp)) +year_month_day::year_month_day(sys_days dp) NOEXCEPT + : year_month_day(from_days(dp.time_since_epoch())) + {} + +CONSTCD14 +inline +year_month_day::year_month_day(local_days dp) NOEXCEPT + : year_month_day(from_days(dp.time_since_epoch())) {} CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;} @@ -2347,7 +2407,8 @@ year_month_day::operator-=(const years& y) NOEXCEPT CONSTCD14 inline -year_month_day::operator day_point() const NOEXCEPT +days +year_month_day::to_days() const NOEXCEPT { static_assert(std::numeric_limits::digits >= 18, "This algorithm has not been ported to a 16 bit unsigned integer"); @@ -2360,14 +2421,21 @@ year_month_day::operator day_point() const NOEXCEPT auto const yoe = static_cast(y - era * 400); // [0, 399] auto const doy = (153*(m > 2 ? m-3 : m+9) + 2)/5 + d-1; // [0, 365] auto const doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096] - return day_point{days{era * 146097 + static_cast(doe) - 719468}}; + return days{era * 146097 + static_cast(doe) - 719468}; } CONSTCD14 inline -year_month_day_last::operator day_point() const NOEXCEPT +year_month_day::operator sys_days() const NOEXCEPT { - return day_point(year()/month()/day()); + return sys_days{to_days()}; +} + +CONSTCD14 +inline +year_month_day::operator local_days() const NOEXCEPT +{ + return local_days{to_days()}; } CONSTCD14 @@ -2449,17 +2517,17 @@ operator<<(std::ostream& os, const year_month_day& ymd) CONSTCD14 inline year_month_day -year_month_day::from_day_point(const day_point& dp) NOEXCEPT +year_month_day::from_days(days dp) NOEXCEPT { static_assert(std::numeric_limits::digits >= 18, "This algorithm has not been ported to a 16 bit unsigned integer"); static_assert(std::numeric_limits::digits >= 20, "This algorithm has not been ported to a 16 bit signed integer"); - auto const z = dp.time_since_epoch().count() + 719468; + auto const z = dp.count() + 719468; auto const era = (z >= 0 ? z : z - 146096) / 146097; auto const doe = static_cast(z - era * 146097); // [0, 146096] auto const yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399] - auto const y = static_cast(yoe) + era * 400; + auto const y = static_cast(yoe) + era * 400; auto const doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365] auto const mp = (5*doy + 2)/153; // [0, 11] auto const d = doy - (153*mp+2)/5 + 1; // [1, 31] @@ -2529,8 +2597,14 @@ year_month_weekday::year_month_weekday(const date::year& y, const date::month& m CONSTCD14 inline -year_month_weekday::year_month_weekday(const day_point& dp) NOEXCEPT - : year_month_weekday(from_day_point(dp)) +year_month_weekday::year_month_weekday(const sys_days& dp) NOEXCEPT + : year_month_weekday(from_days(dp.time_since_epoch())) + {} + +CONSTCD14 +inline +year_month_weekday::year_month_weekday(const local_days& dp) NOEXCEPT + : year_month_weekday(from_days(dp.time_since_epoch())) {} inline @@ -2594,10 +2668,16 @@ year_month_weekday::weekday_indexed() const NOEXCEPT CONSTCD14 inline -year_month_weekday::operator day_point() const NOEXCEPT +year_month_weekday::operator sys_days() const NOEXCEPT { - auto d = day_point(y_/m_/1); - return d + (wdi_.weekday() - date::weekday(d) + days{(wdi_.index()-1)*7}); + return sys_days{to_days()}; +} + +CONSTCD14 +inline +year_month_weekday::operator local_days() const NOEXCEPT +{ + return local_days{to_days()}; } CONSTCD14 @@ -2616,13 +2696,24 @@ year_month_weekday::ok() const NOEXCEPT CONSTCD14 inline year_month_weekday -year_month_weekday::from_day_point(const day_point& dp) NOEXCEPT +year_month_weekday::from_days(days d) NOEXCEPT { + sys_days dp{d}; auto const wd = date::weekday(dp); auto const ymd = year_month_day(dp); return {ymd.year(), ymd.month(), wd[(static_cast(ymd.day())-1)/7+1]}; } +CONSTCD14 +inline +days +year_month_weekday::to_days() const NOEXCEPT +{ + auto d = day_point(y_/m_/1); + return (d + (wdi_.weekday() - date::weekday(d) + days{(wdi_.index()-1)*7}) + ).time_since_epoch(); +} + CONSTCD11 inline bool @@ -2761,10 +2852,16 @@ year_month_weekday_last::weekday_last() const NOEXCEPT CONSTCD14 inline -year_month_weekday_last::operator day_point() const NOEXCEPT +year_month_weekday_last::operator sys_days() const NOEXCEPT { - auto const d = day_point(y_/m_/last); - return d - (date::weekday{d} - wdl_.weekday()); + return sys_days{to_days()}; +} + +CONSTCD14 +inline +year_month_weekday_last::operator local_days() const NOEXCEPT +{ + return local_days{to_days()}; } CONSTCD11 @@ -2775,6 +2872,15 @@ year_month_weekday_last::ok() const NOEXCEPT return y_.ok() && m_.ok() && wdl_.ok(); } +CONSTCD14 +inline +days +year_month_weekday_last::to_days() const NOEXCEPT +{ + auto const d = sys_days(y_/m_/last); + return (d - (date::weekday{d} - wdl_.weekday())).time_since_epoch(); +} + CONSTCD11 inline bool @@ -3723,8 +3829,7 @@ typename std::enable_if std::ratio_less::value , std::ostream& >::type -operator<<(std::ostream& os, - const std::chrono::time_point& tp) +operator<<(std::ostream& os, const sys_time& tp) { auto const dp = floor(tp); return os << year_month_day(dp) << ' ' << make_time(tp-dp); @@ -3732,11 +3837,19 @@ operator<<(std::ostream& os, inline std::ostream& -operator<<(std::ostream& os, const day_point& dp) +operator<<(std::ostream& os, const sys_days& dp) { return os << year_month_day(dp); } +template +inline +std::ostream& +operator<<(std::ostream& os, const local_time& ut) +{ + return os << sys_time{ut.time_since_epoch()}; +} + } // namespace date #endif // DATE_H diff --git a/iso_week.h b/iso_week.h index 9a84d8f..8b15eae 100644 --- a/iso_week.h +++ b/iso_week.h @@ -38,7 +38,10 @@ using years = date::years; // time_point -using day_point = date::day_point; +using sys_days = date::sys_days; + +// deprecated: +using day_point = sys_days; // types @@ -95,7 +98,7 @@ public: explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT; CONSTCD11 weekday(date::weekday wd) NOEXCEPT; explicit weekday(int) = delete; - CONSTCD11 weekday(const day_point& dp) NOEXCEPT; + CONSTCD11 weekday(const sys_days& dp) NOEXCEPT; weekday& operator++() NOEXCEPT; weekday operator++(int) NOEXCEPT; @@ -328,7 +331,7 @@ public: CONSTCD11 iso_week::weeknum weeknum() const NOEXCEPT; CONSTCD11 iso_week::weekday weekday() const NOEXCEPT; - CONSTCD14 operator day_point() const NOEXCEPT; + CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; }; @@ -357,7 +360,7 @@ public: CONSTCD11 year_weeknum_weekday(const iso_week::year& y, const iso_week::weeknum& wn, const iso_week::weekday& wd) NOEXCEPT; CONSTCD14 year_weeknum_weekday(const year_lastweek_weekday& ylwwd) NOEXCEPT; - CONSTCD14 year_weeknum_weekday(const day_point& dp) NOEXCEPT; + CONSTCD14 year_weeknum_weekday(const sys_days& dp) NOEXCEPT; year_weeknum_weekday& operator+=(const years& y) NOEXCEPT; year_weeknum_weekday& operator-=(const years& y) NOEXCEPT; @@ -366,11 +369,11 @@ public: CONSTCD11 iso_week::weeknum weeknum() const NOEXCEPT; CONSTCD11 iso_week::weekday weekday() const NOEXCEPT; - CONSTCD14 operator day_point() const NOEXCEPT; + CONSTCD14 operator sys_days() const NOEXCEPT; CONSTCD14 bool ok() const NOEXCEPT; private: - static CONSTCD14 year_weeknum_weekday from_day_point(const day_point& dp) NOEXCEPT; + static CONSTCD14 year_weeknum_weekday from_day_point(const sys_days& dp) NOEXCEPT; }; CONSTCD11 bool operator==(const year_weeknum_weekday& x, const year_weeknum_weekday& y) NOEXCEPT; @@ -431,7 +434,7 @@ weekday::weekday(date::weekday wd) NOEXCEPT CONSTCD11 inline -weekday::weekday(const day_point& dp) NOEXCEPT +weekday::weekday(const sys_days& dp) NOEXCEPT : wd_(weekday_from_days(dp.time_since_epoch().count())) {} @@ -980,8 +983,8 @@ weeknum year_lastweek::weeknum() const NOEXCEPT { const auto y = date::year{int{y_}}; - const auto s0 = day_point{(y-years{1})/12/date::thu[date::last]}; - const auto s1 = day_point{y/12/date::thu[date::last]}; + const auto s0 = sys_days{(y-years{1})/12/date::thu[date::last]}; + const auto s1 = sys_days{y/12/date::thu[date::last]}; return iso_week::weeknum(date::trunc(s1-s0).count()); } @@ -1273,9 +1276,9 @@ CONSTCD11 inline weekday year_lastweek_weekday::weekday() const NOEXCEPT {return CONSTCD14 inline -year_lastweek_weekday::operator day_point() const NOEXCEPT +year_lastweek_weekday::operator sys_days() const NOEXCEPT { - return day_point{date::year{int{y_}}/date::dec/date::thu[date::last]} + (mon - thu) + return sys_days{date::year{int{y_}}/date::dec/date::thu[date::last]} + (mon - thu) - (mon - wd_); } @@ -1390,7 +1393,7 @@ year_weeknum_weekday::year_weeknum_weekday(const year_lastweek_weekday& ylwwd) N CONSTCD14 inline -year_weeknum_weekday::year_weeknum_weekday(const day_point& dp) NOEXCEPT +year_weeknum_weekday::year_weeknum_weekday(const sys_days& dp) NOEXCEPT : year_weeknum_weekday(from_day_point(dp)) {} @@ -1416,9 +1419,9 @@ CONSTCD11 inline weekday year_weeknum_weekday::weekday() const NOEXCEPT {return CONSTCD14 inline -year_weeknum_weekday::operator day_point() const NOEXCEPT +year_weeknum_weekday::operator sys_days() const NOEXCEPT { - return day_point{date::year{int{y_}-1}/date::dec/date::thu[date::last]} + return sys_days{date::year{int{y_}-1}/date::dec/date::thu[date::last]} + (date::mon - date::thu) + weeks{unsigned{wn_}-1} + (wd_ - mon); } @@ -1433,15 +1436,15 @@ year_weeknum_weekday::ok() const NOEXCEPT CONSTCD14 inline year_weeknum_weekday -year_weeknum_weekday::from_day_point(const day_point& dp) NOEXCEPT +year_weeknum_weekday::from_day_point(const sys_days& dp) NOEXCEPT { const auto wd = iso_week::weekday{dp}; auto y = date::year_month_day{dp + days{3}}.year(); - auto start = day_point{(y - date::years{1})/date::dec/date::thu[date::last]} + (mon-thu); + auto start = sys_days{(y - date::years{1})/date::dec/date::thu[date::last]} + (mon-thu); if (dp < start) { --y; - start = day_point{(y - date::years{1})/date::dec/date::thu[date::last]} + (mon-thu); + start = sys_days{(y - date::years{1})/date::dec/date::thu[date::last]} + (mon-thu); } const auto wn = iso_week::weeknum(date::trunc(dp - start).count() + 1); return {iso_week::year(int{y}), wn, wd}; diff --git a/test/tz_test/tzdata2016d.txt.zip b/test/tz_test/tzdata2016d.txt.zip new file mode 100644 index 0000000000000000000000000000000000000000..8af5ea150edc47bfd0f79ce26d276d9960718cc8 GIT binary patch literal 128096 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 z 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͎N(;~4wBet zjhHu^XLG~76cR`|aK3Je7C-k=NMY;ao}o{duq%#Ez8ge=ZT1pGO??qD^8FPhdj+)GY?d_I5#Yb_aLi2_T+ z15jluPM`+e9GoRJs8=mLzuf_?s2y268(1?`e?V~I=@TSB6u6)qSkyObd@ISJ%7GL% z+g*ji`ER!a%5lH3t=vkL0RHEk0DR$ClbT`SnCA4vJM;9prHfrp?3pk9kK&dtwG6?S zrAt7RFZuIJYyYK-hQ~j0@ah6rAh*!27O*g*Xs91{daNUOX1BVe`NF`5ZN*;9NO}%^ zWOY{=F?RmeyrH)f$61Z(zee9S-}kA;KIVLOw&53kyScC9fSBLV_M*%w{!sedZ0IQN z%&w)Mn{@=trMm{q)pmIoEew`%raNpFDw@=;Ul*-qJ-RVFJ2AmDG$`CZX&*bk`xK8_ z_^&ThDOLRTk<|mt_RrbcL=W*d`tLjQyiT=-oN0-wubtc!>#yP5dWzv5^ZZ7gzSU{H z4mZOGfd>o!W*k=dom?_WmS$THrKbn)`g`cM_pqUDYvkmXlQBfabJoS)!^J+$$_J}# z2kbLiSkwnEHKH#wi*t)D$C*5DPW#(=w_sn7gqrcnBJI9*njLRyXmW3U5uukeUg=Y< zZf}}>HMeqnebsnmAIk{m?M_m`d3%w1n}=G^jDkFV zaQ>?%x|sJbO^U(3yvPh&C%4*xsdd~TTeD+#=s!!Y>uk}k@KCEj2l{4%pOvO); z#a-NG-I&#YO+gsNb(={G`w1m{j<}FHQF^GV(j`qSR=&c7lfF^d zj8ET&OuOz8eI}n`qn~0Um$E&UEp0qHFq?R*Bn$UA{Le|Y#UWnZpH|0%2-36B*uVt% zut-TUtAa_2FujqZA(r`q1Me)(S_&oqu1wj{(y{iKbepAqO%*c2{?sTFfq{2LZ+(9r zp^>e&tclwCdM@TElDIr$%q;f`Rr!OopsiSp2=6-%SiC4dGo@7ZM*+s_>Q*(>3hb~_XyGz zmIdtXXFRX=+kA<1!N??q^p~E{TtV59SaL#hRKldTp@D5$P}caq8qm0dNju{NFP}Su`t03uSC$VwuI-01uvE^V#sR5&d&4z!Q9eD zSjDS?<2A`0IP|0X80Tx^%!HS&4;YxY0v*3>?~>zdCsR8KbONLte4 za8}yE@$9*?Bc{hrj!2%oV-YA6u@S4XS{CEBZFSI0>ZUtFVOzEwuuwi+CAYc9*s}D_ zYWRq$`eu`z+pCW>e|IEpyIY;f2lJZuCb*-wZ`1lu*~rR7Z`}0M_S6#uK;lHpHvFu8 z8dj7Fr-cbdNE-VO?B#ZlM8v-?{>MLVqA&jgx#&0Ki;Di6+5S<)Kj05$US>qmZ$|ug hEX#4q{4Xq7%T@dz23-zog$Rlq3*RhguZ&~h`ag<}H%9;f literal 0 HcmV?d00001 diff --git a/test/tz_test/validate.cpp b/test/tz_test/validate.cpp index 15a0313..59ab6b8 100644 --- a/test/tz_test/validate.cpp +++ b/test/tz_test/validate.cpp @@ -2,38 +2,42 @@ #include void -test_info(const date::Zone* zone, const date::Info& info) +test_info(const date::time_zone* zone, const date::Info& info) { using namespace date; using namespace std::chrono; auto begin = info.begin; auto end = info.end - microseconds{1}; - auto mid = begin + (end - begin) /2 ; + auto mid = begin + (end - begin) /2; + using sys_microseconds = sys_time; + using zoned_microseconds = zoned_time; + using local_microseconds = local_time; + zoned_microseconds local{zone}; - if (begin > day_point{jan/1/1700}) + if (begin > sys_days{jan/1/1700}) { - auto local = zone->to_local(begin).first; - auto prev_local = zone->to_local(begin - seconds{1}).first; - if (prev_local < local - seconds{1}) + auto prev_local = local; + local = begin; + prev_local = begin - seconds{1}; + auto slocal = local.get_local_time(); + auto plocal = prev_local.get_local_time(); + if (plocal < slocal - seconds{1}) { - assert(zone->to_sys(local) == begin); - auto imaginary = prev_local + (local - seconds{1} - prev_local) / 2; + assert(sys_microseconds{local} == begin); try { - zone->to_sys(imaginary); + local = plocal + (slocal - seconds{1} - plocal) / 2; assert(false); } catch (const nonexistent_local_time&) { } } - else if (prev_local > local - seconds{1}) + else if (plocal > slocal - seconds{1}) { - auto ambiguous = local - seconds{1} + - (prev_local - (local - seconds{1})) / 2; try { - zone->to_sys(ambiguous); + local = slocal - seconds{1} + (plocal - (slocal - seconds{1})) / 2; assert(false); } catch (const ambiguous_local_time&) @@ -42,33 +46,34 @@ test_info(const date::Zone* zone, const date::Info& info) } } - auto local = zone->to_local(mid).first; - assert(zone->to_sys(local) == mid); + local = mid; + assert(sys_microseconds{local} == mid); - if (end < day_point{jan/1/3000}) + if (end < sys_days{jan/1/3000}) { - auto local = zone->to_local(end).first; - auto next_local = zone->to_local(info.end).first; - if (next_local < local + microseconds{1}) + local = end; + auto next_local = local; + next_local = info.end; + auto slocal = local.get_local_time(); + auto nlocal = next_local.get_local_time(); + if (nlocal < slocal + microseconds{1}) { - auto ambiguous = next_local + (local + microseconds{1} - next_local) / 2; try { - zone->to_sys(ambiguous); + local = nlocal + (slocal + microseconds{1} - nlocal) / 2; assert(false); } catch (const ambiguous_local_time&) { } } - else if (next_local > local + microseconds{1}) + else if (nlocal > slocal + microseconds{1}) { - assert(zone->to_sys(local) == end); - auto imaginary = local + microseconds{1} + - (next_local - (local + microseconds{1})) / 2; + assert(sys_microseconds{local} == end); try { - zone->to_sys(imaginary); + local = slocal + microseconds{1} + + (nlocal - (slocal + microseconds{1})) / 2; assert(false); } catch (const nonexistent_local_time&) @@ -96,8 +101,8 @@ main() { std::cout << name << '\n'; auto z = locate_zone(name); - auto begin = day_point(jan/1/year::min()) + 0s; - auto end = day_point(jan/1/2035) + 0s; + auto begin = sys_days(jan/1/year::min()) + 0s; + auto end = sys_days(jan/1/2035) + 0s; auto info = z->get_info(begin, tz::utc); std::cout << "Initially: "; if (info.offset >= 0s) @@ -122,7 +127,7 @@ main() auto dp = floor(begin); auto ymd = year_month_day(dp); auto time = make_time(begin - dp); - std::cout << ymd << 'T' << time << "Z "; + std::cout << ymd << ' ' << time << "Z "; if (info.offset >= 0s) std::cout << '+'; std::cout << make_time(info.offset); diff --git a/test/tz_test/zone.pass.cpp b/test/tz_test/zone.pass.cpp index eed4698..30329e5 100644 --- a/test/tz_test/zone.pass.cpp +++ b/test/tz_test/zone.pass.cpp @@ -6,10 +6,10 @@ main() { using namespace std; using namespace date; - static_assert( is_nothrow_destructible{}, ""); - static_assert(!is_default_constructible{}, ""); - static_assert(!is_copy_constructible{}, ""); - static_assert(!is_copy_assignable{}, ""); - static_assert( is_nothrow_move_constructible{}, ""); - static_assert( is_nothrow_move_assignable{}, ""); + static_assert( is_nothrow_destructible{}, ""); + static_assert(!is_default_constructible{}, ""); + static_assert(!is_copy_constructible{}, ""); + static_assert(!is_copy_assignable{}, ""); + static_assert( is_nothrow_move_constructible{}, ""); + static_assert( is_nothrow_move_assignable{}, ""); } diff --git a/tz.cpp b/tz.cpp index ab4870f..c3fa838 100644 --- a/tz.cpp +++ b/tz.cpp @@ -20,6 +20,10 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +// +// Our apologies. When the previous paragraph was written, lowercase had not yet +// been invented (that woud involve another several millennia of evolution). +// We did not mean to shout. #include "tz_private.h" @@ -118,6 +122,8 @@ CONSTDATA auto max_year = date::year::max(); // Arbitrary day of the year that will be away from any limits. // Used with year::min() and year::max(). CONSTDATA auto boring_day = date::aug/18; +CONSTDATA auto min_day = date::jan/1; +CONSTDATA auto max_day = date::dec/31; // +-------------------+ // | End Configuration | @@ -549,7 +555,7 @@ parse_signed_time(std::istream& in) // MonthDayTime -MonthDayTime::MonthDayTime(second_point tp, tz timezone) +MonthDayTime::MonthDayTime(local_seconds tp, tz timezone) : zone_(timezone) { using namespace date; @@ -606,8 +612,8 @@ MonthDayTime::compare(date::year y, const MonthDayTime& x, date::year yx, { if (zone_ != x.zone_) { - auto dp0 = to_day_point(y); - auto dp1 = x.to_day_point(yx); + auto dp0 = to_sys_days(y); + auto dp1 = x.to_sys_days(yx); if (std::abs((dp0-dp1).count()) > 1) return dp0 < dp1 ? -1 : 1; if (zone_ == tz::local) @@ -642,7 +648,7 @@ MonthDayTime::compare(date::year y, const MonthDayTime& x, date::year yx, return t0 < t1 ? -1 : t0 == t1 ? 0 : 1; } -second_point +sys_seconds MonthDayTime::to_sys(date::year y, std::chrono::seconds offset, std::chrono::seconds save) const { @@ -677,23 +683,23 @@ MonthDayTime::U::operator=(const pair& x) return *this; } -date::day_point -MonthDayTime::to_day_point(date::year y) const +date::sys_days +MonthDayTime::to_sys_days(date::year y) const { using namespace std::chrono; using namespace date; switch (type_) { case month_day: - return day_point(y/u.month_day_); + return sys_days(y/u.month_day_); case month_last_dow: - return day_point(y/u.month_weekday_last_); + return sys_days(y/u.month_weekday_last_); case lteq: { auto const x = y/u.month_day_weekday_.month_day_; auto const wd1 = weekday(x); auto const wd0 = u.month_day_weekday_.weekday_; - return day_point(x) - (wd1-wd0); + return sys_days(x) - (wd1-wd0); } case gteq: break; @@ -701,13 +707,13 @@ MonthDayTime::to_day_point(date::year y) const auto const x = y/u.month_day_weekday_.month_day_; auto const wd1 = u.month_day_weekday_.weekday_; auto const wd0 = weekday(x); - return day_point(x) + (wd1-wd0); + return sys_days(x) + (wd1-wd0); } -second_point +sys_seconds MonthDayTime::to_time_point(date::year y) const { - return to_day_point(y) + h_ + m_ + s_; + return to_sys_days(y) + h_ + m_ + s_; } void @@ -721,7 +727,7 @@ MonthDayTime::canonicalize(date::year y) return; case month_last_dow: { - auto const ymd = year_month_day(y/u.month_weekday_last_); + auto const ymd = year_month_day(sys_days{y/u.month_weekday_last_}); u.month_day_ = ymd.month()/ymd.day(); type_ = month_day; return; @@ -731,7 +737,7 @@ MonthDayTime::canonicalize(date::year y) auto const x = y/u.month_day_weekday_.month_day_; auto const wd1 = weekday(x); auto const wd0 = u.month_day_weekday_.weekday_; - auto const ymd = year_month_day(day_point(x) - (wd1-wd0)); + auto const ymd = year_month_day(sys_days(x) - (wd1-wd0)); u.month_day_ = ymd.month()/ymd.day(); type_ = month_day; return; @@ -741,7 +747,7 @@ MonthDayTime::canonicalize(date::year y) auto const x = y/u.month_day_weekday_.month_day_; auto const wd1 = u.month_day_weekday_.weekday_; auto const wd0 = weekday(x); - auto const ymd = year_month_day(day_point(x) + (wd1-wd0)); + auto const ymd = year_month_day(sys_days(x) + (wd1-wd0)); u.month_day_ = ymd.month()/ymd.day(); type_ = month_day; return; @@ -1218,9 +1224,9 @@ Rule::split_overlaps(std::vector& rules) rules.shrink_to_fit(); } -// Zone +// time_zone -Zone::zonelet::~zonelet() +time_zone::zonelet::~zonelet() { #if !defined(_MSC_VER) || (_MSC_VER >= 1900) using minutes = std::chrono::minutes; @@ -1232,14 +1238,14 @@ Zone::zonelet::~zonelet() #endif } -Zone::zonelet::zonelet() +time_zone::zonelet::zonelet() { #if !defined(_MSC_VER) || (_MSC_VER >= 1900) ::new(&u.rule_) std::string(); #endif } -Zone::zonelet::zonelet(const zonelet& i) +time_zone::zonelet::zonelet(const zonelet& i) : gmtoff_(i.gmtoff_) , tag_(i.tag_) , format_(i.format_) @@ -1266,7 +1272,7 @@ Zone::zonelet::zonelet(const zonelet& i) #endif } -Zone::Zone(const std::string& s) +time_zone::time_zone(const std::string& s) #if LAZY_INIT : adjusted_(new std::once_flag{}) #endif @@ -1290,7 +1296,7 @@ Zone::Zone(const std::string& s) } void -Zone::add(const std::string& s) +time_zone::add(const std::string& s) { try { @@ -1310,7 +1316,7 @@ Zone::add(const std::string& s) } void -Zone::parse_info(std::istream& in) +time_zone::parse_info(std::istream& in) { using namespace date; using namespace std::chrono; @@ -1326,7 +1332,7 @@ Zone::parse_info(std::istream& in) if (in.eof() || in.peek() == '#') { zonelet.until_year_ = year::max(); - zonelet.until_date_ = MonthDayTime(boring_day, tz::utc); + zonelet.until_date_ = MonthDayTime(max_day, tz::utc); } else { @@ -1489,8 +1495,9 @@ find_rule_for_zone(const std::pair& eqr, static std::pair find_rule_for_zone(const std::pair& eqr, - const second_point& tp_utc, const second_point& tp_std, - const second_point& tp_loc) + const sys_seconds& tp_utc, + const local_seconds& tp_std, + const local_seconds& tp_loc) { using namespace std::chrono; using namespace date; @@ -1508,10 +1515,10 @@ find_rule_for_zone(const std::pair& eqr, found = tp_utc < r->mdt().to_time_point(ry); break; case tz::standard: - found = tp_std < r->mdt().to_time_point(ry); + found = sys_seconds{tp_std.time_since_epoch()} < r->mdt().to_time_point(ry); break; case tz::local: - found = tp_loc < r->mdt().to_time_point(ry); + found = sys_seconds{tp_loc.time_since_epoch()} < r->mdt().to_time_point(ry); break; } if (found) @@ -1536,7 +1543,7 @@ find_rule(const std::pair& first_rule, using namespace date; auto r = first_rule.first; auto ry = first_rule.second; - Info x{day_point(year::min()/boring_day), day_point(year::max()/boring_day), + Info x{sys_days(year::min()/min_day), sys_days(year::max()/max_day), seconds{0}, initial_save, initial_abbrev}; while (r != nullptr) { @@ -1569,7 +1576,7 @@ find_rule(const std::pair& first_rule, x.end = r->mdt().to_sys(ry, offset, x.save); } else - x.end = day_point(year::max()/boring_day); + x.end = sys_days(year::max()/max_day); break; } x.save = r->save(); @@ -1580,7 +1587,7 @@ find_rule(const std::pair& first_rule, } void -Zone::adjust_infos(const std::vector& rules) +time_zone::adjust_infos(const std::vector& rules) { using namespace std::chrono; using namespace date; @@ -1640,7 +1647,7 @@ Zone::adjust_infos(const std::vector& rules) final_save = z.last_rule_.first->save(); } z.until_utc_ = z.until_date_.to_sys(z.until_year_, z.gmtoff_, final_save); - z.until_std_ = z.until_utc_ + z.gmtoff_; + z.until_std_ = local_seconds{z.until_utc_.time_since_epoch()} + z.gmtoff_; z.until_loc_ = z.until_std_ + final_save; if (z.tag_ == zonelet::has_rule) @@ -1751,7 +1758,7 @@ format_abbrev(std::string format, const std::string& variable, std::chrono::seco } Info -Zone::get_info(std::chrono::system_clock::time_point tp, tz timezone) const +time_zone::get_info_impl(sys_seconds tp, tz timezone) const { using namespace std::chrono; using namespace date; @@ -1761,17 +1768,18 @@ Zone::get_info(std::chrono::system_clock::time_point tp, tz timezone) const throw std::runtime_error("The year " + std::to_string(static_cast(y)) + " is out of range:[" + std::to_string(static_cast(min_year)) + ", " + std::to_string(static_cast(max_year)) + "]"); - auto tps = floor(tp); #if LAZY_INIT - std::call_once(*adjusted_, [this]() - { - const_cast(this)->adjust_infos(get_tzdb().rules); - }); + std::call_once(*adjusted_, + [this]() + { + const_cast(this)->adjust_infos(get_tzdb().rules); + }); #endif - auto i = std::upper_bound(zonelets_.begin(), zonelets_.end(), tps, - [timezone](second_point t, const zonelet& zl) + auto i = std::upper_bound(zonelets_.begin(), zonelets_.end(), tp, + [timezone](sys_seconds t, const zonelet& zl) { - return timezone == tz::utc ? t < zl.until_utc_ : t < zl.until_loc_; + return timezone == tz::utc ? t < zl.until_utc_ : + t < sys_seconds{zl.until_loc_.time_since_epoch()}; }); Info r{}; @@ -1782,7 +1790,7 @@ Zone::get_info(std::chrono::system_clock::time_point tp, tz timezone) const if (i != zonelets_.begin()) r.begin = i[-1].until_utc_; else - r.begin = day_point(year::min()/boring_day); + r.begin = sys_days(year::min()/min_day); r.end = i->until_utc_; r.offset = i->gmtoff_ + i->u.save_; r.save = i->u.save_; @@ -1792,15 +1800,15 @@ Zone::get_info(std::chrono::system_clock::time_point tp, tz timezone) const if (i != zonelets_.begin()) r.begin = i[-1].until_utc_; else - r.begin = day_point(year::min()/boring_day); + r.begin = sys_days(year::min()/min_day); r.end = i->until_utc_; r.offset = i->gmtoff_; } else { r = find_rule(i->first_rule_, i->last_rule_, y, i->gmtoff_, - MonthDayTime(tps, timezone), i->initial_save_, - i->initial_abbrev_); + MonthDayTime(local_seconds{tp.time_since_epoch()}, timezone), + i->initial_save_, i->initial_abbrev_); r.offset = i->gmtoff_ + r.save; if (i != zonelets_.begin() && r.begin < i[-1].until_utc_) r.begin = i[-1].until_utc_; @@ -1814,7 +1822,7 @@ Zone::get_info(std::chrono::system_clock::time_point tp, tz timezone) const } std::ostream& -operator<<(std::ostream& os, const Zone& z) +operator<<(std::ostream& os, const time_zone& z) { using namespace date; using namespace std::chrono; @@ -1822,10 +1830,11 @@ operator<<(std::ostream& os, const Zone& z) os.fill(' '); os.flags(std::ios::dec | std::ios::left); #if LAZY_INIT - std::call_once(*z.adjusted_, [&z]() - { - const_cast(z).adjust_infos(get_tzdb().rules); - }); + std::call_once(*z.adjusted_, + [&z]() + { + const_cast(z).adjust_infos(get_tzdb().rules); + }); #endif os.width(35); os << z.name_; @@ -1837,7 +1846,7 @@ operator<<(std::ostream& os, const Zone& z) os << ' '; os << make_time(s.gmtoff_) << " "; os.width(15); - if (s.tag_ != Zone::zonelet::has_save) + if (s.tag_ != time_zone::zonelet::has_save) os << s.u.rule_; else { @@ -2120,7 +2129,7 @@ init_tzdb() } else if (word == "Zone") { - db.zones.push_back(Zone(line)); + db.zones.push_back(time_zone(line)); continue_zone = true; } else if (line[0] == '\t' && continue_zone) @@ -2182,12 +2191,12 @@ get_tzdb() return ref; } -const Zone* +const time_zone* locate_zone(const std::string& tz_name) { const auto& db = get_tzdb(); auto zi = std::lower_bound(db.zones.begin(), db.zones.end(), tz_name, - [](const Zone& z, const std::string& nm) + [](const time_zone& z, const std::string& nm) { return z.name() < nm; }); @@ -2201,7 +2210,7 @@ locate_zone(const std::string& tz_name) if (li != db.links.end() && li->name() == tz_name) { zi = std::lower_bound(db.zones.begin(), db.zones.end(), li->target(), - [](const Zone& z, const std::string& nm) + [](const time_zone& z, const std::string& nm) { return z.name() < nm; }); @@ -2215,7 +2224,7 @@ locate_zone(const std::string& tz_name) #ifdef TZ_TEST #ifdef _WIN32 -const Zone* +const time_zone* locate_native_zone(const std::string& native_tz_name) { std::string standard_tz_name; @@ -2305,7 +2314,7 @@ operator<<(std::ostream& os, const Info& r) #ifdef _WIN32 -const Zone* +const time_zone* current_zone() { #if TIMEZONE_MAPPING @@ -2346,7 +2355,7 @@ current_zone() #else // ! WIN32 -const Zone* +const time_zone* current_zone() { // On some versions of some linux distro's (e.g. Ubuntu), diff --git a/tz.h b/tz.h index 46e6386..1ff0aa5 100644 --- a/tz.h +++ b/tz.h @@ -22,6 +22,10 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +// +// Our apologies. When the previous paragraph was written, lowercase had not yet +// been invented (that woud involve another several millennia of evolution). +// We did not mean to shout. // Get more recent database at http://www.iana.org/time-zones @@ -93,9 +97,6 @@ static_assert(HAS_REMOTE_API == 0 ? AUTO_DOWNLOAD == 0 : true, namespace date { -using second_point = std::chrono::time_point; - enum class tz {utc, local, standard}; enum class choose {earliest, latest}; @@ -103,42 +104,37 @@ class nonexistent_local_time : public std::runtime_error { public: - template - nonexistent_local_time(std::chrono::time_point> tp, - second_point first, const std::string& first_abbrev, - second_point last, const std::string& last_abbrev, - second_point time_sys); + template + nonexistent_local_time(local_time tp, local_seconds first, + const std::string& first_abbrev, local_seconds last, + const std::string& last_abbrev, sys_seconds time_sys); private: - template + template static std::string - make_msg(std::chrono::time_point> tp, - second_point first, const std::string& first_abbrev, - second_point last, const std::string& last_abbrev, - second_point time_sys); + make_msg(local_time tp, + local_seconds first, const std::string& first_abbrev, + local_seconds last, const std::string& last_abbrev, + sys_seconds time_sys); }; -template +template inline -nonexistent_local_time::nonexistent_local_time( - std::chrono::time_point> tp, - second_point first, const std::string& first_abbrev, - second_point last, const std::string& last_abbrev, - second_point time_sys) +nonexistent_local_time::nonexistent_local_time(local_time tp, + local_seconds first, + const std::string& first_abbrev, + local_seconds last, + const std::string& last_abbrev, + sys_seconds time_sys) : std::runtime_error(make_msg(tp, first, first_abbrev, last, last_abbrev, time_sys)) {} -template +template std::string -nonexistent_local_time::make_msg(std::chrono::time_point> tp, - second_point first, const std::string& first_abbrev, - second_point last, const std::string& last_abbrev, - second_point time_sys) +nonexistent_local_time::make_msg(local_time tp, local_seconds first, + const std::string& first_abbrev, local_seconds last, + const std::string& last_abbrev, sys_seconds time_sys) { using namespace date; std::ostringstream os; @@ -154,29 +150,25 @@ class ambiguous_local_time : public std::runtime_error { public: - template - ambiguous_local_time(std::chrono::time_point> tp, - std::chrono::seconds first_offset, + template + ambiguous_local_time(local_time tp, std::chrono::seconds first_offset, const std::string& first_abbrev, std::chrono::seconds second_offset, const std::string& second_abbrev); private: - template + template static std::string - make_msg(std::chrono::time_point> tp, + make_msg(local_time tp, std::chrono::seconds first_offset, const std::string& first_abbrev, std::chrono::seconds second_offset, const std::string& second_abbrev); }; -template +template inline ambiguous_local_time::ambiguous_local_time( - std::chrono::time_point> tp, + local_time tp, std::chrono::seconds first_offset, const std::string& first_abbrev, std::chrono::seconds second_offset, @@ -185,10 +177,9 @@ ambiguous_local_time::ambiguous_local_time( second_abbrev)) {} -template +template std::string -ambiguous_local_time::make_msg(std::chrono::time_point> tp, +ambiguous_local_time::make_msg(local_time tp, std::chrono::seconds first_offset, const std::string& first_abbrev, std::chrono::seconds second_offset, @@ -197,8 +188,10 @@ ambiguous_local_time::make_msg(std::chrono::time_point +inline +Duration +sum(Duration d) +{ + return d; +} + +template +inline +std::common_type_t +sum(D1 d1, D2 d2, Durations ...durations) +{ + return d1 + d2 + sum(durations...); +} + +} // detail + +template +class zoned_time +{ + const time_zone* zone_; + sys_time tp_; + +public: + zoned_time(sys_time st); + explicit zoned_time(const time_zone* z); + explicit zoned_time(const std::string& name); + + template , + sys_time>::value + >> + zoned_time(const zoned_time& zt); + + zoned_time(const time_zone* z, local_time tp); + zoned_time(const std::string& name, local_time tp); + zoned_time(const time_zone* z, local_time tp, choose c); + zoned_time(const std::string& name, local_time tp, choose c); + + zoned_time(const time_zone* z, const zoned_time& zt); + zoned_time(const std::string& name, const zoned_time& zt); + zoned_time(const time_zone* z, const zoned_time& zt, choose c); + zoned_time(const std::string& name, const zoned_time& zt, choose c); + + zoned_time(const time_zone* z, const sys_time& st); + zoned_time(const std::string& name, const sys_time& st); + + zoned_time& operator=(sys_time st); + zoned_time& operator=(local_time ut); + + explicit operator local_time() const; + operator sys_time() const; + + const time_zone* get_time_zone() const; + local_time get_local_time() const; + sys_time get_sys_time() const; + + template + friend + bool + operator==(const zoned_time& x, const zoned_time& y); + + template + friend + std::ostream& + operator<<(std::ostream& os, const zoned_time& t); + +private: + + static_assert(std::ratio_less_equal::value, + "zoned_time must have a precision of hours or finer"); +}; + +using zoned_seconds = zoned_time; + +// Should equality bother with comparing zones? +// If zones don't matter, add operator< ? +template +inline +bool +operator==(const zoned_time& x, const zoned_time& y) +{ + return x.zone == y.zone && x.tp == y.tp; +} + +template +inline +bool +operator!=(const zoned_time& x, const zoned_time& y) +{ + return !(x == y); +} + +class time_zone { private: struct zonelet; @@ -229,10 +333,58 @@ private: public: #if !defined(_MSC_VER) || (_MSC_VER >= 1900) - Zone(Zone&&) = default; - Zone& operator=(Zone&&) = default; -#else // defined(_MSC_VER) || (_MSC_VER >= 1900) - Zone(Zone&& src) + time_zone(time_zone&&) = default; + time_zone& operator=(time_zone&&) = default; +#else // defined(_MSC_VER) && (_MSC_VER < 1900) + time_zone(time_zone&& src); + time_zone& operator=(time_zone&& src); +#endif // defined(_MSC_VER) && (_MSC_VER < 1900) + + explicit time_zone(const std::string& s); + + const std::string& name() const; + + template Info get_info(sys_time st) const; + template Info get_info(local_time tp) const; + +private: + template + sys_time::type> + to_sys(local_time tp) const; + + template + sys_time::type> + to_sys(local_time tp, choose z) const; + + template + local_time::type> + to_local(sys_time tp) const; + +public: + friend bool operator==(const time_zone& x, const time_zone& y); + friend bool operator< (const time_zone& x, const time_zone& y); + friend std::ostream& operator<<(std::ostream& os, const time_zone& z); + + void add(const std::string& s); + void adjust_infos(const std::vector& rules); + +private: + Info get_info_impl(sys_seconds tp, tz timezone) const; + + void parse_info(std::istream& in); + + template + sys_time::type> + to_sys_impl(local_time tp, choose z, + std::integral_constant do_throw) const; + + template friend class zoned_time; +}; + +#if defined(_MSC_VER) && (_MSC_VER < 1900) + +inline +time_zone::time_zone(time_zone&& src) : name_(std::move(src.name_)) , zonelets_(std::move(src.zonelets_)) #if LAZY_INIT @@ -240,162 +392,119 @@ public: #endif {} - Zone& operator=(Zone&& src) - { - name_ = std::move(src.name_); - zonelets_ = std::move(src.zonelets_); -#if LAZY_INIT - adjusted_ = std::move(src.adjusted_); -#endif - return *this; - } -#endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) - - explicit Zone(const std::string& s); - - const std::string& name() const {return name_;} - Info get_info(std::chrono::system_clock::time_point tp, tz timezone) const; - - template - Info - get_info(std::chrono::time_point> tp, - tz timezone) const - { - using namespace std::chrono; - return get_info(floor(tp), timezone); - } - - template - std::chrono::time_point, - std::chrono::seconds>::type> - to_sys(std::chrono::time_point> tp) const; - - template - std::chrono::time_point, - std::chrono::seconds>::type> - to_sys(std::chrono::time_point> tp, - choose z) const; - - template - std::pair - < - std::chrono::time_point, - std::chrono::seconds>::type>, - std::string - > - to_local(std::chrono::time_point> tp) const; - - friend bool operator==(const Zone& x, const Zone& y); - friend bool operator< (const Zone& x, const Zone& y); - friend std::ostream& operator<<(std::ostream& os, const Zone& z); - - void add(const std::string& s); - void adjust_infos(const std::vector& rules); - -private: - void parse_info(std::istream& in); - - template - std::chrono::time_point, - std::chrono::seconds>::type> - to_sys_impl(std::chrono::time_point> tp, - choose z, std::integral_constant do_throw) const; -}; - -template inline -std::chrono::time_point, - std::chrono::seconds>::type> -Zone::to_sys(std::chrono::time_point> tp) const +time_zone& +time_zone::operator=(time_zone&& src) +{ + name_ = std::move(src.name_); + zonelets_ = std::move(src.zonelets_); +#if LAZY_INIT + adjusted_ = std::move(src.adjusted_); +#endif + return *this; +} + +#endif // defined(_MSC_VER) && (_MSC_VER < 1900) + +inline +const std::string& +time_zone::name() const +{ + return name_; +} + +template +inline +Info +time_zone::get_info(sys_time st) const +{ + using namespace std::chrono; + return get_info_impl(floor(st), tz::utc); +} + +template +inline +Info +time_zone::get_info(local_time tp) const +{ + using namespace std::chrono; + return get_info_impl(floor(sys_time{tp.time_since_epoch()}), + tz::local); +} + +template +inline +sys_time::type> +time_zone::to_sys(local_time tp) const { return to_sys_impl(tp, choose{}, std::true_type{}); } -template +template inline -std::chrono::time_point, - std::chrono::seconds>::type> -Zone::to_sys(std::chrono::time_point> tp, choose z) const +sys_time::type> +time_zone::to_sys(local_time tp, choose z) const { return to_sys_impl(tp, z, std::false_type{}); } -template +template inline -std::pair -< - std::chrono::time_point, - std::chrono::seconds>::type>, - std::string -> -Zone::to_local(std::chrono::time_point> tp) const +local_time::type> +time_zone::to_local(sys_time tp) const { - auto const i = get_info(tp, tz::utc); - return {tp + i.offset, i.abbrev}; + using LT = local_time::type>; + auto i = get_info(tp); + return LT{(tp + i.offset).time_since_epoch()}; } -inline bool operator==(const Zone& x, const Zone& y) {return x.name_ == y.name_;} -inline bool operator< (const Zone& x, const Zone& y) {return x.name_ < y.name_;} +inline bool operator==(const time_zone& x, const time_zone& y) {return x.name_ == y.name_;} +inline bool operator< (const time_zone& x, const time_zone& y) {return x.name_ < y.name_;} -inline bool operator!=(const Zone& x, const Zone& y) {return !(x == y);} -inline bool operator> (const Zone& x, const Zone& y) {return y < x;} -inline bool operator<=(const Zone& x, const Zone& y) {return !(y < x);} -inline bool operator>=(const Zone& x, const Zone& y) {return !(x < y);} +inline bool operator!=(const time_zone& x, const time_zone& y) {return !(x == y);} +inline bool operator> (const time_zone& x, const time_zone& y) {return y < x;} +inline bool operator<=(const time_zone& x, const time_zone& y) {return !(y < x);} +inline bool operator>=(const time_zone& x, const time_zone& y) {return !(x < y);} -template -std::chrono::time_point, - std::chrono::seconds>::type> -Zone::to_sys_impl(std::chrono::time_point> tp, - choose z, std::integral_constant do_throw) const +template +sys_time::type> +time_zone::to_sys_impl(local_time tp, choose z, + std::integral_constant do_throw) const { using namespace date; using namespace std::chrono; - auto i = get_info(tp, tz::local); - auto tp_sys = tp - i.offset; + auto i = get_info(tp); + auto tp_sys = sys_time{tp.time_since_epoch()} - i.offset; if (floor(tp_sys) - i.begin <= days{1}) { - if (floor(tp) < i.begin + i.offset) + auto ut_begin = local_seconds{i.begin.time_since_epoch()} + i.offset; + if (floor(tp) < ut_begin) { if (do_throw) { - auto prev = get_info(i.begin - seconds{1}, tz::utc); - throw nonexistent_local_time(tp, i.begin + prev.offset, prev.abbrev, - i.begin + i.offset, i.abbrev, i.begin); + auto prev = get_info(i.begin - seconds{1}); + auto ut_prev_begin = local_seconds{i.begin.time_since_epoch()} + prev.offset; + throw nonexistent_local_time(tp, ut_prev_begin, prev.abbrev, + ut_begin, i.abbrev, i.begin); } return i.begin; } assert(floor(tp) >= - i.begin + get_info(i.begin - seconds{1}, tz::utc).offset); + local_seconds{i.begin.time_since_epoch()} + + get_info(i.begin - seconds{1}).offset); } if (i.end - floor(tp_sys) <= days{1}) { - assert(floor(tp) < i.end + i.offset); - auto next = get_info(i.end, tz::utc); - if (floor(tp) >= i.end + next.offset) + assert(floor(tp) < local_seconds{i.end.time_since_epoch()} + i.offset); + auto next = get_info(i.end); + if (floor(tp) >= local_seconds{i.end.time_since_epoch()} + next.offset) { if (do_throw) throw ambiguous_local_time(tp, i.offset, i.abbrev, - next.offset, next.abbrev); + next.offset, next.abbrev); if (z == choose::earliest) return tp_sys; - return tp - next.offset; + return sys_time{tp.time_since_epoch()} - next.offset; } } return tp_sys; @@ -426,12 +535,12 @@ inline bool operator>=(const Link& x, const Link& y) {return !(x < y);} class Leap { private: - second_point date_; + sys_seconds date_; public: explicit Leap(const std::string& s); - second_point date() const {return date_;} + sys_seconds date() const {return date_;} friend bool operator==(const Leap& x, const Leap& y) {return x.date_ == y.date_;} friend bool operator< (const Leap& x, const Leap& y) {return x.date_ < y.date_;} @@ -439,8 +548,7 @@ public: template friend bool - operator==(const Leap& x, - const std::chrono::time_point& y) + operator==(const Leap& x, const sys_time& y) { return x.date_ == y; } @@ -448,8 +556,7 @@ public: template friend bool - operator< (const Leap& x, - const std::chrono::time_point& y) + operator< (const Leap& x, const sys_time& y) { return x.date_ < y; } @@ -457,8 +564,7 @@ public: template friend bool - operator< (const std::chrono::time_point& x, - const Leap& y) + operator< (const sys_time& x, const Leap& y) { return x < y.date_; } @@ -474,8 +580,7 @@ inline bool operator>=(const Leap& x, const Leap& y) {return !(x < y);} template inline bool -operator==(const std::chrono::time_point& x, - const Leap& y) +operator==(const sys_time& x, const Leap& y) { return y == x; } @@ -483,8 +588,7 @@ operator==(const std::chrono::time_point& x template inline bool -operator!=(const Leap& x, - const std::chrono::time_point& y) +operator!=(const Leap& x, const sys_time& y) { return !(x == y); } @@ -492,8 +596,7 @@ operator!=(const Leap& x, template inline bool -operator!=(const std::chrono::time_point& x, - const Leap& y) +operator!=(const sys_time& x, const Leap& y) { return !(x == y); } @@ -501,8 +604,7 @@ operator!=(const std::chrono::time_point& x template inline bool -operator> (const Leap& x, - const std::chrono::time_point& y) +operator> (const Leap& x, const sys_time& y) { return y < x; } @@ -510,8 +612,7 @@ operator> (const Leap& x, template inline bool -operator> (const std::chrono::time_point& x, - const Leap& y) +operator> (const sys_time& x, const Leap& y) { return y < x; } @@ -519,8 +620,7 @@ operator> (const std::chrono::time_point& x template inline bool -operator<=(const Leap& x, - const std::chrono::time_point& y) +operator<=(const Leap& x, const sys_time& y) { return !(y < x); } @@ -528,8 +628,7 @@ operator<=(const Leap& x, template inline bool -operator<=(const std::chrono::time_point& x, - const Leap& y) +operator<=(const sys_time& x, const Leap& y) { return !(y < x); } @@ -537,8 +636,7 @@ operator<=(const std::chrono::time_point& x template inline bool -operator>=(const Leap& x, - const std::chrono::time_point& y) +operator>=(const Leap& x, const sys_time& y) { return !(x < y); } @@ -546,8 +644,7 @@ operator>=(const Leap& x, template inline bool -operator>=(const std::chrono::time_point& x, - const Leap& y) +operator>=(const sys_time& x, const Leap& y) { return !(x < y); } @@ -596,11 +693,11 @@ struct timezone_info struct TZ_DB { - std::string version; - std::vector zones; - std::vector links; - std::vector leaps; - std::vector rules; + std::string version; + std::vector zones; + std::vector links; + std::vector leaps; + std::vector rules; #if TIMEZONE_MAPPING // TODO! These need some protection. std::vector mappings; @@ -653,13 +750,250 @@ bool remote_download(const std::string& version); bool remote_install(const std::string& version); #endif -const Zone* locate_zone(const std::string& tz_name); +const time_zone* locate_zone(const std::string& tz_name); #ifdef TZ_TEST #ifdef _WIN32 -const Zone* locate_native_zone(const std::string& native_tz_name); +const time_zone* locate_native_zone(const std::string& native_tz_name); #endif #endif -const Zone* current_zone(); +const time_zone* current_zone(); + +// zoned_time + +template +inline +zoned_time::zoned_time(sys_time st) + : zone_(locate_zone("UTC")) + , tp_(st) + {} + +template +inline +zoned_time::zoned_time(const time_zone* z) + : zone_(z) + {assert(zone_ != nullptr);} + +template +inline +zoned_time::zoned_time(const std::string& name) + : zoned_time(locate_zone(name)) + {} + +template +inline +zoned_time::zoned_time(const time_zone* z, local_time t) + : zone_(z) + , tp_(floor(z->to_sys(t))) + {} + +template +inline +zoned_time::zoned_time(const std::string& name, local_time t) + : zoned_time(locate_zone(name), t) + {} + +template +inline +zoned_time::zoned_time(const time_zone* z, local_time t, choose c) + : zone_(z) + , tp_(floor(z->to_sys(t, c))) + {} + +template +inline +zoned_time::zoned_time(const std::string& name, local_time t, + choose c) + : zoned_time(locate_zone(name), t, c) + {} + +template +template +inline +zoned_time::zoned_time(const zoned_time& zt) + : zone_(zt.zone_) + , tp_(zt.tp_) + {} + +template +inline +zoned_time::zoned_time(const time_zone* z, const zoned_time& zt) + : zone_(z) + , tp_(zt.tp_) + {} + +template +inline +zoned_time::zoned_time(const std::string& name, const zoned_time& zt) + : zoned_time(locate_zone(name), zt) + {} + +template +inline +zoned_time::zoned_time(const time_zone* z, const zoned_time& zt, choose) + : zoned_time(z, zt) + {} + +template +inline +zoned_time::zoned_time(const std::string& name, + const zoned_time& zt, choose c) + : zoned_time(locate_zone(name), zt, c) + {} + +template +inline +zoned_time::zoned_time(const time_zone* z, const sys_time& st) + : zone_(z) + , tp_(st) + {} + +template +inline +zoned_time::zoned_time(const std::string& name, const sys_time& st) + : zoned_time(locate_zone(name), st) + {} + + +template +inline +zoned_time& +zoned_time::operator=(sys_time st) +{ + tp_ = st; + return *this; +} + +template +inline +zoned_time& +zoned_time::operator=(local_time ut) +{ + tp_ = floor(zone_->to_sys(ut)); + return *this; +} + +template +inline +zoned_time::operator local_time() const +{ + return get_local_time(); +} + +template +inline +zoned_time::operator sys_time() const +{ + return get_sys_time(); +} + +template +inline +const time_zone* +zoned_time::get_time_zone() const +{ + return zone_; +} + +template +inline +local_time +zoned_time::get_local_time() const +{ + return floor(zone_->to_local(tp_)); +} + +template +inline +sys_time +zoned_time::get_sys_time() const +{ + return tp_; +} + +// make_zoned_time + +template +inline +zoned_time +make_zoned(sys_time tp) +{ + return zoned_time{tp}; +} + +template +inline +zoned_time +make_zoned(const time_zone* zone, local_time tp) +{ + return {zone, tp}; +} + +template +inline +zoned_time +make_zoned(const std::string& name, local_time tp) +{ + return {name, tp}; +} + +template +inline +zoned_time +make_zoned(const time_zone* zone, const zoned_time& zt) +{ + return {zone, zt}; +} + +template +inline +zoned_time +make_zoned(const std::string& name, const zoned_time& zt) +{ + return {name, zt}; +} + +template +inline +zoned_time +make_zoned(const time_zone* zone, const zoned_time& zt, choose c) +{ + return {zone, zt, c}; +} + +template +inline +zoned_time +make_zoned(const std::string& name, const zoned_time& zt, choose c) +{ + return {name, zt, c}; +} + +template +inline +zoned_time +make_zoned(const time_zone* zone, const sys_time& st) +{ + return {zone, st}; +} + +template +inline +zoned_time +make_zoned(const std::string& name, const sys_time& st) +{ + return {name, st}; +} + + +template +inline +std::ostream& +operator<<(std::ostream& os, const zoned_time& t) +{ + // this should not use two lookups! + return os << floor(t.zone_->to_local(t.tp_)) << ' ' + << t.zone_->get_info(t.tp_).abbrev; +} class utc_clock { @@ -676,15 +1010,17 @@ public: static std::chrono::time_point::type> - sys_to_utc(std::chrono::time_point t); + sys_to_utc(sys_time t); template static - std::chrono::time_point::type> + sys_time::type> utc_to_sys(std::chrono::time_point t); }; +template + using utc_time = std::chrono::time_point; + inline utc_clock::time_point utc_clock::now() NOEXCEPT @@ -694,28 +1030,24 @@ utc_clock::now() NOEXCEPT } template -std::chrono::time_point::type> -utc_clock::sys_to_utc(std::chrono::time_point t) +utc_time::type> +utc_clock::sys_to_utc(sys_time t) { using namespace std::chrono; using duration = typename std::common_type::type; - using time_point = std::chrono::time_point; auto const& leaps = get_tzdb().leaps; auto const lt = std::upper_bound(leaps.begin(), leaps.end(), t); - return time_point{t.time_since_epoch() + seconds{lt-leaps.begin()}}; + return utc_time{t.time_since_epoch() + seconds{lt-leaps.begin()}}; } template -std::chrono::time_point::type> -utc_clock::utc_to_sys(std::chrono::time_point t) +sys_time::type> +utc_clock::utc_to_sys(utc_time t) { using namespace std::chrono; using duration = typename std::common_type::type; - using time_point = std::chrono::time_point; auto const& leaps = get_tzdb().leaps; - auto tp = time_point{t.time_since_epoch()}; + 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]) @@ -723,6 +1055,25 @@ utc_clock::utc_to_sys(std::chrono::time_point t) return tp; } +template + using utc_time = std::chrono::time_point; + +template +inline +sys_time +to_sys_time(utc_time ut) +{ + return utc_clock::utc_to_sys(ut); +} + +template +inline +utc_time +to_utc_time(sys_time st) +{ + return utc_clock::sys_to_utc(st); +} + // format namespace detail @@ -731,8 +1082,7 @@ namespace detail template std::string format(const std::locale& loc, std::string format, - std::chrono::time_point tp, - const Zone* zone) + local_time tp, const time_zone* zone = nullptr) { // Handle these specially // %S append fractional seconds if tp has precision finer than seconds @@ -763,13 +1113,10 @@ format(const std::locale& loc, std::string format, break; case 'z': if (zone == nullptr) - { - format.replace(i, 2, "+0000"); - i += 5 - 1; - } + throw std::runtime_error("Can not format local_time with %z"); else { - auto info = zone->get_info(tp, tz::local); + auto info = zone->get_info(tp); auto offset = duration_cast(info.offset); ostringstream os; if (offset >= minutes{0}) @@ -783,13 +1130,10 @@ format(const std::locale& loc, std::string format, break; case 'Z': if (zone == nullptr) - { - format.replace(i, 2, "UTC"); - i += 3 - 1; - } + throw std::runtime_error("Can not format local_time with %z"); else { - auto info = zone->get_info(tp, tz::local); + auto info = zone->get_info(tp); format.replace(i, 2, info.abbrev); i += info.abbrev.size() - 1; } @@ -799,7 +1143,7 @@ format(const std::locale& loc, std::string format, } auto& f = use_facet>(loc); ostringstream os; - auto tt = system_clock::to_time_t(tp); + auto tt = system_clock::to_time_t(sys_time{tp.time_since_epoch()}); std::tm tm{}; #ifndef _MSC_VER gmtime_r(&tt, &tm); @@ -815,36 +1159,53 @@ format(const std::locale& loc, std::string format, template inline std::string -format(const std::locale& loc, std::string format, - std::chrono::time_point tp, - const Zone* zone = nullptr) +format(const std::locale& loc, std::string format, local_time tp) { - return detail::format(loc, std::move(format), tp, zone); -} - -inline -std::string -format(const std::locale& loc, std::string format, day_point tp, - const Zone* zone = nullptr) -{ - return detail::format(loc, std::move(format), tp, zone); + return detail::format(loc, std::move(format), tp); } template inline std::string -format(std::string format, - std::chrono::time_point tp, - const Zone* zone = nullptr) +format(std::string format, local_time tp) { - return detail::format(std::locale{}, std::move(format), tp, zone); + return detail::format(std::locale{}, std::move(format), tp); } +template inline std::string -format(std::string format, day_point tp, const Zone* zone = nullptr) +format(const std::locale& loc, std::string format, const zoned_time& tp) { - return detail::format(std::locale{}, std::move(format), tp, zone); + return detail::format(loc, std::move(format), tp.get_local_time(), + tp.get_time_zone()); +} + +template +inline +std::string +format(std::string format, const zoned_time& tp) +{ + return detail::format(std::locale{}, std::move(format), tp.get_local_time(), + tp.get_time_zone()); +} + +template +inline +std::string +format(const std::locale& loc, std::string format, sys_time tp) +{ + return detail::format(loc, std::move(format), + local_time{tp.time_since_epoch()}, locate_zone("UTC")); +} + +template +inline +std::string +format(std::string format, sys_time tp) +{ + return detail::format(std::locale{}, std::move(format), + local_time{tp.time_since_epoch()}, locate_zone("UTC")); } // parse @@ -855,8 +1216,7 @@ namespace detail template void parse(std::istream& is, const std::string& format, - std::chrono::time_point& tp, - std::string* abbrev = nullptr) + sys_time& tp, std::string* abbrev = nullptr) { using namespace std; using namespace std::chrono; @@ -896,7 +1256,7 @@ parse(std::istream& is, const std::string& format, if (!is.fail()) subseconds = duration_cast(duration{s}); else - err &= ios_base::failbit; + err |= ios_base::failbit; } else { @@ -928,10 +1288,10 @@ parse(std::istream& is, const std::string& format, offset = -offset; } else - err &= ios_base::failbit; + err |= ios_base::failbit; } else - err &= ios_base::failbit; + err |= ios_base::failbit; } break; case 'Z': @@ -944,7 +1304,7 @@ parse(std::istream& is, const std::string& format, { is >> temp_abbrev; if (is.fail()) - err &= ios_base::failbit; + err |= ios_base::failbit; } } break; @@ -977,8 +1337,7 @@ parse(std::istream& is, const std::string& format, template inline void -parse(std::istream& is, const std::string& format, - std::chrono::time_point& tp) +parse(std::istream& is, const std::string& format, sys_time& tp) { detail::parse(is, format, tp); } @@ -986,8 +1345,7 @@ parse(std::istream& is, const std::string& format, template inline void -parse(std::istream& is, const std::string& format, - std::chrono::time_point& tp, +parse(std::istream& is, const std::string& format, sys_time& tp, std::string& abbrev) { detail::parse(is, format, tp, &abbrev); diff --git a/tz_private.h b/tz_private.h index c706638..497813b 100644 --- a/tz_private.h +++ b/tz_private.h @@ -3,7 +3,7 @@ // The MIT License (MIT) // -// Copyright (c) 2015 Howard Hinnant +// Copyright (c) 2015, 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -22,6 +22,10 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +// +// Our apologies. When the previous paragraph was written, lowercase had not yet +// been invented (that woud involve another several millennia of evolution). +// We did not mean to shout. #include "tz.h" @@ -80,7 +84,7 @@ private: public: MonthDayTime() = default; - MonthDayTime(second_point tp, tz timezone); + MonthDayTime(local_seconds tp, tz timezone); MonthDayTime(const date::month_day& md, tz timezone); date::day day() const; @@ -89,11 +93,11 @@ public: void canonicalize(date::year y); - second_point + sys_seconds to_sys(date::year y, std::chrono::seconds offset, std::chrono::seconds save) const; - date::day_point to_day_point(date::year y) const; + sys_days to_sys_days(date::year y) const; - second_point to_time_point(date::year y) const; + sys_seconds to_time_point(date::year y) const; int compare(date::year y, const MonthDayTime& x, date::year yx, std::chrono::seconds offset, std::chrono::minutes prev_save) const; @@ -181,7 +185,7 @@ inline bool operator> (const std::string& x, const Rule& y) {return y < x;} inline bool operator<=(const std::string& x, const Rule& y) {return !(y < x);} inline bool operator>=(const std::string& x, const Rule& y) {return !(x < y);} -struct Zone::zonelet +struct time_zone::zonelet { enum tag {has_rule, has_save, is_empty}; @@ -203,14 +207,14 @@ struct Zone::zonelet U& operator=(const U&) = delete; } u; - std::string format_; - date::year until_year_{0}; - MonthDayTime until_date_; - second_point until_utc_; - second_point until_std_; - second_point until_loc_; - std::chrono::minutes initial_save_{}; - std::string initial_abbrev_; + std::string format_; + date::year until_year_{0}; + MonthDayTime until_date_; + sys_seconds until_utc_; + local_seconds until_std_; + local_seconds until_loc_; + std::chrono::minutes initial_save_{}; + std::string initial_abbrev_; std::pair first_rule_{nullptr, date::year::min()}; std::pair last_rule_{nullptr, date::year::max()};