diff --git a/test/tz_test/zoned_time.pass.cpp b/test/tz_test/zoned_time.pass.cpp new file mode 100644 index 0000000..70f3a83 --- /dev/null +++ b/test/tz_test/zoned_time.pass.cpp @@ -0,0 +1,464 @@ +// The MIT License (MIT) +// +// Copyright (c) 2017 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 +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// 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. + +// template +// class zoned_time +// { +// public: +// using duration = typename std::common_type::type; +// +// zoned_time(); +// zoned_time(const sys_time& st); +// explicit zoned_time(const time_zone* z); +// explicit zoned_time(std::string_view name); +// +// template , +// sys_time>::value +// >::type> +// zoned_time(const zoned_time& zt) NOEXCEPT; +// +// zoned_time(const time_zone* z, const local_time& tp); +// zoned_time(std::string_view name, const local_time& tp); +// zoned_time(const time_zone* z, const local_time& tp, choose c); +// zoned_time(std::string_view name, const local_time& tp, choose c); +// +// zoned_time(const time_zone* z, const zoned_time& zt); +// zoned_time(std::string_view name, const zoned_time& zt); +// zoned_time(const time_zone* z, const zoned_time& zt, choose); +// zoned_time(std::string_view name, const zoned_time& zt, choose); +// +// zoned_time(const time_zone* z, const sys_time& st); +// zoned_time(std::string_view name, const sys_time& st); +// +// zoned_time& operator=(const sys_time& st); +// zoned_time& operator=(const local_time& ut); +// +// explicit operator sys_time() const; +// explicit operator local_time() const; +// +// const time_zone* get_time_zone() const; +// local_time get_local_time() const; +// sys_time get_sys_time() const; +// sys_info get_info() const; +// +// template +// friend +// bool +// operator==(const zoned_time& x, const zoned_time& y); +// +// template +// friend +// std::basic_ostream& +// operator<<(std::basic_ostream& os, const zoned_time& t); +// }; +// +// using zoned_seconds = zoned_time; +// +// template +// inline +// bool +// operator!=(const zoned_time& x, const zoned_time& y); +// +// template +// zoned_time(sys_time) +// -> zoned_time>; +// +// template +// zoned_time(Zone, sys_time) +// -> zoned_time>; +// +// template +// zoned_time(Zone, local_time, choose = choose::earliest) +// -> zoned_time>; +// +// template +// zoned_time(Zone, zoned_time, choose = choose::earliest) +// -> zoned_time>; + +#include "tz.h" +#include +#include +#include + +int +main() +{ + using namespace std; + using namespace std::chrono; + using namespace date; + static_assert( is_nothrow_destructible{}, ""); + static_assert( is_default_constructible{}, ""); + static_assert( is_nothrow_copy_constructible{}, ""); + static_assert( is_nothrow_copy_assignable{}, ""); + static_assert( is_nothrow_move_constructible{}, ""); + static_assert( is_nothrow_move_assignable{}, ""); + + static_assert(is_same::duration, seconds>{}, ""); + static_assert(is_same{}, ""); + static_assert(is_same::duration, milliseconds>{}, ""); + + // zoned_time(); + { + zoned_seconds zt; + assert(zt.get_sys_time() == sys_seconds{}); + assert(zt.get_time_zone()->name() == "Etc/UTC"); + } + + // zoned_time(const sys_time& st); + { + static_assert(!is_convertible{}, ""); + static_assert( is_constructible{}, ""); + static_assert( is_convertible{}, ""); + static_assert(!is_convertible, zoned_seconds>{}, ""); + static_assert(!is_constructible>{}, ""); + + auto now = floor(system_clock::now()); + zoned_seconds zt = now; + assert(zt.get_sys_time() == now); + assert(zt.get_time_zone()->name() == "Etc/UTC"); + } + + // explicit zoned_time(const time_zone* z); + { + static_assert(!is_convertible{}, ""); + static_assert( is_constructible{}, ""); + zoned_seconds zt{locate_zone("America/New_York")}; + assert(zt.get_sys_time() == sys_seconds{}); + assert(zt.get_time_zone()->name() == "America/New_York"); + } + + // explicit zoned_time(std::string_view name); + { + static_assert(!is_convertible{}, ""); + static_assert( is_constructible{}, ""); + static_assert( is_constructible{}, ""); + static_assert( is_constructible{}, ""); + zoned_seconds zt{"America/New_York"}; + assert(zt.get_sys_time() == sys_seconds{}); + assert(zt.get_time_zone()->name() == "America/New_York"); + } + + // template , + // sys_time>::value + // >::type> + // zoned_time(const zoned_time& zt) NOEXCEPT; + { + static_assert( is_convertible, zoned_seconds>{}, ""); + static_assert(!is_constructible, zoned_seconds>{}, ""); + zoned_time zt1{"America/New_York", sys_days{2017_y/jul/5}}; + zoned_seconds zt2 = zt1; + assert(zt2.get_sys_time() == sys_days{2017_y/jul/5}); + assert(zt2.get_time_zone()->name() == "America/New_York"); + } + + // zoned_time(const time_zone* z, const local_time& tp); + { + static_assert( is_constructible{}, ""); + zoned_seconds zt = {locate_zone("America/New_York"), local_days{2017_y/jul/5}}; + assert(zt.get_local_time() == local_days{2017_y/jul/5}); + assert(zt.get_time_zone()->name() == "America/New_York"); + try + { + zoned_seconds zt1 = {locate_zone("America/New_York"), + local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}}; + assert(false); + } + catch(const nonexistent_local_time&) + { + } + try + { + zoned_seconds zt1 = {locate_zone("America/New_York"), + local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}}; + assert(false); + } + catch(const ambiguous_local_time&) + { + } + } + + // zoned_time(std::string_view name, const local_time& tp); + { + static_assert( is_constructible{}, ""); + static_assert( is_constructible{}, ""); + zoned_seconds zt = {"America/New_York", local_days{2017_y/jul/5}}; + assert(zt.get_local_time() == local_days{2017_y/jul/5}); + assert(zt.get_time_zone()->name() == "America/New_York"); + try + { + zoned_seconds zt1 = {"America/New_York", + local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}}; + assert(false); + } + catch(const nonexistent_local_time&) + { + } + try + { + zoned_seconds zt1 = {"America/New_York", + local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}}; + assert(false); + } + catch(const ambiguous_local_time&) + { + } + } + + // zoned_time(const time_zone* z, const local_time& tp, choose c); + { + static_assert( is_constructible{}, ""); + zoned_seconds zt = {locate_zone("America/New_York"), + local_days{2017_y/jul/5} + hours{2} + minutes{15}, + choose::earliest}; + assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{6} + minutes{15}); + assert(zt.get_time_zone()->name() == "America/New_York"); + + zt = {locate_zone("America/New_York"), + local_days{2017_y/jul/5} + hours{2} + minutes{15}, + choose::latest}; + assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{6} + minutes{15}); + assert(zt.get_time_zone()->name() == "America/New_York"); + + static_assert( is_constructible{}, ""); + zoned_seconds zt1 = {locate_zone("America/New_York"), + local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}, + choose::earliest}; + assert(zt1.get_sys_time() == sys_days{2017_y/mar/12} + hours{7}); + assert(zt1.get_time_zone()->name() == "America/New_York"); + + zoned_seconds zt2 = {locate_zone("America/New_York"), + local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}, + choose::latest}; + assert(zt2.get_sys_time() == sys_days{2017_y/mar/12} + hours{7}); + assert(zt2.get_time_zone()->name() == "America/New_York"); + + zoned_seconds zt3 = {locate_zone("America/New_York"), + local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}, + choose::earliest}; + assert(zt3.get_sys_time() == sys_days{2017_y/nov/5} + hours{5} + minutes{15}); + assert(zt3.get_time_zone()->name() == "America/New_York"); + + zoned_seconds zt4 = {locate_zone("America/New_York"), + local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}, + choose::latest}; + assert(zt4.get_sys_time() == sys_days{2017_y/nov/5} + hours{6} + minutes{15}); + assert(zt4.get_time_zone()->name() == "America/New_York"); + } + + // zoned_time(std::string_view name, const local_time& tp, choose c); + { + static_assert( is_constructible{}, ""); + static_assert( is_constructible{}, ""); + zoned_seconds zt = {"America/New_York", + local_days{2017_y/jul/5} + hours{2} + minutes{15}, + choose::earliest}; + assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{6} + minutes{15}); + assert(zt.get_time_zone()->name() == "America/New_York"); + + zt = {"America/New_York", + local_days{2017_y/jul/5} + hours{2} + minutes{15}, + choose::latest}; + assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{6} + minutes{15}); + assert(zt.get_time_zone()->name() == "America/New_York"); + + static_assert( is_constructible{}, ""); + zoned_seconds zt1 = {"America/New_York", + local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}, + choose::earliest}; + assert(zt1.get_sys_time() == sys_days{2017_y/mar/12} + hours{7}); + assert(zt1.get_time_zone()->name() == "America/New_York"); + + zoned_seconds zt2 = {"America/New_York", + local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}, + choose::latest}; + assert(zt2.get_sys_time() == sys_days{2017_y/mar/12} + hours{7}); + assert(zt2.get_time_zone()->name() == "America/New_York"); + + zoned_seconds zt3 = {"America/New_York", + local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}, + choose::earliest}; + assert(zt3.get_sys_time() == sys_days{2017_y/nov/5} + hours{5} + minutes{15}); + assert(zt3.get_time_zone()->name() == "America/New_York"); + + zoned_seconds zt4 = {"America/New_York", + local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}, + choose::latest}; + assert(zt4.get_sys_time() == sys_days{2017_y/nov/5} + hours{6} + minutes{15}); + assert(zt4.get_time_zone()->name() == "America/New_York"); + } + + // zoned_time(const time_zone* z, const sys_time& st); + { + static_assert( is_constructible{}, ""); + + zoned_seconds zt = {locate_zone("America/New_York"), + sys_days{2017_y/jul/5} + hours{2} + minutes{15}}; + assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{2} + minutes{15}); + assert(zt.get_time_zone()->name() == "America/New_York"); + } + + // zoned_time(std::string_view name, const sys_time& st); + { + static_assert( is_constructible{}, ""); + static_assert( is_constructible{}, ""); + + zoned_seconds zt = {"America/New_York", + sys_days{2017_y/jul/5} + hours{2} + minutes{15}}; + assert(zt.get_sys_time() == sys_days{2017_y/jul/5} + hours{2} + minutes{15}); + assert(zt.get_time_zone()->name() == "America/New_York"); + } + + // zoned_time& operator=(const sys_time& st); + { + static_assert( is_assignable{}, ""); + + zoned_seconds zt{"America/New_York"}; + zt = sys_days{2017_y/jul/5}; + assert(zt.get_sys_time() == sys_days{2017_y/jul/5}); + assert(zt.get_time_zone()->name() == "America/New_York"); + } + + // zoned_time& operator=(const local_time& st); + { + static_assert( is_assignable{}, ""); + + zoned_seconds zt{"America/New_York"}; + zt = local_days{2017_y/jul/5}; + assert(zt.get_local_time() == local_days{2017_y/jul/5}); + assert(zt.get_time_zone()->name() == "America/New_York"); + try + { + zt = {"America/New_York", + local_days{2017_y/mar/sun[2]} + hours{2} + minutes{15}}; + assert(false); + } + catch(const nonexistent_local_time&) + { + assert(zt.get_local_time() == local_days{2017_y/jul/5}); + assert(zt.get_time_zone()->name() == "America/New_York"); + } + try + { + zt = {"America/New_York", + local_days{2017_y/nov/sun[1]} + hours{1} + minutes{15}}; + assert(false); + } + catch(const ambiguous_local_time&) + { + assert(zt.get_local_time() == local_days{2017_y/jul/5}); + assert(zt.get_time_zone()->name() == "America/New_York"); + } + } + + // explicit operator sys_time() const; + { + static_assert(!is_convertible{}, ""); + static_assert( is_constructible{}, ""); + auto now = floor(system_clock::now()); + const zoned_seconds zt = {"America/New_York", now}; + assert(sys_seconds{zt} == now); + } + + // explicit operator local_time() const; + { + static_assert(!is_convertible{}, ""); + static_assert( is_constructible{}, ""); + auto now = local_days{2017_y/jul/5} + hours{23} + minutes{1} + seconds{48}; + const zoned_seconds zt = {"America/New_York", now}; + assert(local_seconds{zt} == now); + } + + // const time_zone* get_time_zone() const; + { + const zoned_seconds zt{"America/New_York"}; + assert(zt.get_time_zone() == locate_zone("America/New_York")); + } + + // local_time get_local_time() const; + { + const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + + hours{3} + minutes{7} + seconds{9}}; + assert(zt.get_local_time() == local_days{2017_y/jul/5} + + hours{23} + minutes{7} + seconds{9}); + } + + // sys_time get_sys_time() const; + { + const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + + hours{3} + minutes{7} + seconds{9}}; + assert(zt.get_sys_time() == sys_days{2017_y/jul/6} + + hours{3} + minutes{7} + seconds{9}); + } + + // sys_info get_info() const; + { + const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + + hours{3} + minutes{7} + seconds{9}}; + auto info = zt.get_info(); + assert(info.begin == sys_days{2017_y/mar/12} + hours{7}); + assert(info.end == sys_days{2017_y/nov/5} + hours{6}); + assert(info.offset == hours{-4}); + assert(info.save != minutes{0}); + assert(info.abbrev == "EDT"); + } + + // template + // bool + // operator==(const zoned_time& x, const zoned_time& y); + { + const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + + hours{3} + minutes{7} + seconds{9}}; + const zoned_seconds zt1{"America/New_York", sys_days{2017_y/jul/6} + + hours{3} + minutes{7} + seconds{10}}; + assert(zt == zt); + assert(!(zt == zt1)); + } + + // template + // bool + // operator!=(const zoned_time& x, const zoned_time& y); + { + const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + + hours{3} + minutes{7} + seconds{9}}; + const zoned_seconds zt1{"America/New_York", sys_days{2017_y/jul/6} + + hours{3} + minutes{7} + seconds{10}}; + assert(!(zt != zt)); + assert(zt != zt1); + } + + // template + // std::basic_ostream& + // operator<<(std::basic_ostream& os, const zoned_time& t); + { + const zoned_seconds zt{"America/New_York", sys_days{2017_y/jul/6} + + hours{3} + minutes{7} + seconds{9}}; + std::ostringstream test; + test << zt; + assert(test.str() == "2017-07-05 23:07:09 EDT"); + } +}