diff options
author | Mark de Wever <koraq@xs4all.nl> | 2024-04-17 21:00:22 +0200 |
---|---|---|
committer | Mark de Wever <koraq@xs4all.nl> | 2024-07-07 17:32:40 +0200 |
commit | 5195d3905de900a09a9c78ee843c28f0939cdf62 (patch) | |
tree | d4e42e383c0de9675a24ffbe56a051dd3fc07300 | |
parent | 6d6dade0997a414431bf852742cd68c24d274e27 (diff) | |
download | llvm-5195d3905de900a09a9c78ee843c28f0939cdf62.zip llvm-5195d3905de900a09a9c78ee843c28f0939cdf62.tar.gz llvm-5195d3905de900a09a9c78ee843c28f0939cdf62.tar.bz2 |
[libc++][TZDB] Finishes zoned_time member functions.users/mordante/zoned_time__members
Note the implementation of
zoned_time& operator=(const local_time<Duration>& lt);
is not correct; however the wording cannot be easily implemented. It could
be if the object caches the local_time assigned. However this does not
seem to intended. The current implementation matches MSVC STL and
libstdc++.
Implements parts of:
- P0355 Extending to chrono Calendars and Time Zones
8 files changed, 855 insertions, 2 deletions
diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h index 08f7f37..101a9f5 100644 --- a/libcxx/include/__chrono/zoned_time.h +++ b/libcxx/include/__chrono/zoned_time.h @@ -18,6 +18,7 @@ # include <__chrono/calendar.h> # include <__chrono/duration.h> +# include <__chrono/sys_info.h> # include <__chrono/system_clock.h> # include <__chrono/time_zone.h> # include <__chrono/tzdb_list.h> @@ -147,8 +148,29 @@ public: } && is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>) : zoned_time{__traits::locate_zone(__name), __zt, __c} {} + _LIBCPP_HIDE_FROM_ABI zoned_time& operator=(const sys_time<_Duration>& __tp) { + __tp_ = __tp; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI zoned_time& operator=(const local_time<_Duration>& __tp) { + // TODO TZDB This seems wrong. + // Assigning a non-existant or abiguous time will throw and not satisfy + // the post condition. This seems quite odd; I constructed an object with + // choose::earliest and that choice is not respected. + // what did LEWG do with this. + // MSVC STL and libstdc++ behave the same + __tp_ = __zone_->to_sys(__tp); + return *this; + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI operator sys_time<duration>() const { return get_sys_time(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit operator local_time<duration>() const { return get_local_time(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _TimeZonePtr get_time_zone() const { return __zone_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_time<duration> get_local_time() const { return __zone_->to_local(__tp_); } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_time<duration> get_sys_time() const { return __tp_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_info get_info() const { return __zone_->get_info(__tp_); } private: _TimeZonePtr __zone_; diff --git a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp index e8337cb..32a67dc 100644 --- a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp @@ -81,7 +81,15 @@ void test() { { std::chrono::zoned_time<std::chrono::seconds> zt; - zt.get_time_zone(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - zt.get_sys_time(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + static_cast<std::chrono::sys_seconds>(zt); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + static_cast<std::chrono::local_seconds>(zt); + + zt.get_time_zone(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + zt.get_local_time(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + zt.get_sys_time(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + zt.get_info(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } } diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/assign.local_time.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/assign.local_time.pass.cpp new file mode 100644 index 0000000..5e1feb9 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/assign.local_time.pass.cpp @@ -0,0 +1,243 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// zoned_time& operator=(const local_time<Duration>& st); + +// TODO TZDB Investigate the issues in this test, this seems like +// a design issue of the class. +// +// [time.zone.zonedtime.members]/3 +// Effects: After assignment, get_local_time() == lt. +// This assignment has no effect on the return value of get_time_zone(). +// +// The test cases describe the issues. + +#include <cassert> +#include <chrono> +#include <concepts> +#include <type_traits> + +#include "test_macros.h" + +namespace cr = std::chrono; + +// Tests unique conversions. To make sure the test is does not depend on changes +// in the database it uses a time zone with a fixed offset. +static void test_unique() { + // common_type_t<duration, seconds> -> duration + { + using duration = cr::nanoseconds; + using sys_time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == sys_time_point{duration{42}}); + assert(zt.get_local_time() == local_time_point{duration{42} - cr::hours{1}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = local_time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == sys_time_point{duration{99} + cr::hours{1}}); + assert(zt.get_local_time() == local_time_point{duration{99}}); + } + { + using duration = cr::microseconds; + using sys_time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == sys_time_point{duration{42}}); + assert(zt.get_local_time() == local_time_point{duration{42} - cr::hours{1}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = local_time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == sys_time_point{duration{99} + cr::hours{1}}); + assert(zt.get_local_time() == local_time_point{duration{99}}); + } + { + using duration = cr::milliseconds; + using sys_time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == sys_time_point{duration{42}}); + assert(zt.get_local_time() == local_time_point{duration{42} - cr::hours{1}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = local_time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == sys_time_point{duration{99} + cr::hours{1}}); + assert(zt.get_local_time() == local_time_point{duration{99}}); + } + // common_type_t<seconds, seconds> -> seconds + { + using duration = cr::seconds; + using sys_time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == sys_time_point{duration{42}}); + assert(zt.get_local_time() == local_time_point{duration{42} - cr::hours{1}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = local_time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == sys_time_point{duration{99} + cr::hours{1}}); + assert(zt.get_local_time() == local_time_point{duration{99}}); + } + // common_type_t<duration, seconds> -> seconds + { + using duration = cr::days; + using sys_time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == cr::sys_seconds{duration{42}}); + assert(zt.get_local_time() == cr::local_seconds{duration{42} - cr::hours{1}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = local_time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == cr::sys_seconds{duration{99} + cr::hours{1}}); + assert(zt.get_local_time() == cr::local_seconds{duration{99}}); + } + { + using duration = cr::weeks; + using sys_time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == cr::sys_seconds{duration{42}}); + assert(zt.get_local_time() == cr::local_seconds{duration{42} - cr::hours{1}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = local_time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == cr::sys_seconds{duration{99} + cr::hours{1}}); + assert(zt.get_local_time() == cr::local_seconds{duration{99}}); + } + /* This does not work; due to using __tp_ = __zone_->to_sys(__tp); + * Here the ambiguous/non-existent exception can't stream months and years, + * leading to a compilation error. + { + using duration = cr::months; + using sys_time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == cr::sys_seconds{duration{42}}); + assert(zt.get_local_time() == cr::local_seconds{duration{42} - cr::hours{1}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = local_time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == cr::sys_seconds{duration{99} + cr::hours{1}}); + assert(zt.get_local_time() == cr::local_seconds{duration{99}}); + } */ +} + +// Tests non-existant conversions. +static void test_nonexistent() { +#ifndef TEST_HAS_NO_EXCEPTIONS + using namespace std::literals::chrono_literals; + + const cr::time_zone* tz = cr::locate_zone("Europe/Berlin"); + + // Z Europe/Berlin 0:53:28 - LMT 1893 Ap + // ... + // 1 DE CE%sT 1980 + // 1 E CE%sT + // + // ... + // R E 1981 ma - Mar lastSu 1u 1 S + // R E 1996 ma - O lastSu 1u 0 - + + // Pick an historic date where it's well known what the time zone rules were. + // This makes it unlikely updates to the database change these rules. + cr::local_time<cr::seconds> time{(cr::sys_days{cr::March / 30 / 1986} + 2h + 30min).time_since_epoch()}; + + using duration = cr::seconds; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{tz}; + + bool thrown = false; + try { + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = time; + } catch (const cr::nonexistent_local_time&) { + thrown = true; + } + // There is no system type that can represent the current local time. So the + // assertion passes. The current implementation throws an exception too. + assert(zt.get_local_time() != time); + assert(thrown); +#endif // TEST_HAS_NO_EXCEPTIONS +} + +// Tests ambiguous conversions. +static void test_ambiguous() { +#ifndef TEST_HAS_NO_EXCEPTIONS + using namespace std::literals::chrono_literals; + + const cr::time_zone* tz = cr::locate_zone("Europe/Berlin"); + + // Z Europe/Berlin 0:53:28 - LMT 1893 Ap + // ... + // 1 DE CE%sT 1980 + // 1 E CE%sT + // + // ... + // R E 1981 ma - Mar lastSu 1u 1 S + // R E 1996 ma - O lastSu 1u 0 - + + // Pick an historic date where it's well known what the time zone rules were. + // This makes it unlikely updates to the database change these rules. + cr::local_time<cr::seconds> time{(cr::sys_days{cr::September / 28 / 1986} + 2h + 30min).time_since_epoch()}; + + using duration = cr::seconds; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{tz}; + + bool thrown = false; + try { + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = time; + } catch (const cr::ambiguous_local_time&) { + thrown = true; + } + // There is no system type that can represent the current local time. So the + // assertion passes. The current implementation throws an exception too. + assert(zt.get_local_time() != time); + assert(thrown); +#endif // TEST_HAS_NO_EXCEPTIONS +} + +int main(int, char**) { + test_unique(); + test_nonexistent(); + test_ambiguous(); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/assign.sys_time.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/assign.sys_time.pass.cpp new file mode 100644 index 0000000..0eeba7a --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/assign.sys_time.pass.cpp @@ -0,0 +1,136 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// zoned_time& operator=(const sys_time<Duration>& st); + +#include <cassert> +#include <chrono> +#include <concepts> +#include <type_traits> + +namespace cr = std::chrono; + +int main(int, char**) { + { + using duration = cr::nanoseconds; + using time_point = cr::sys_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{42}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{99}}); + } + { + using duration = cr::microseconds; + using time_point = cr::sys_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{42}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{99}}); + } + { + using duration = cr::milliseconds; + using time_point = cr::sys_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{42}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{99}}); + } + { + using duration = cr::seconds; + using time_point = cr::sys_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{42}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{99}}); + } + { + using duration = cr::days; + using time_point = cr::sys_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{42}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{99}}); + } + { + using duration = cr::weeks; + using time_point = cr::sys_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{42}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{99}}); + } + { + using duration = cr::months; + using time_point = cr::sys_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{42}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{99}}); + } + { + using duration = cr::years; + using time_point = cr::sys_time<duration>; + using zoned_time = cr::zoned_time<duration>; + zoned_time zt{time_point{duration{42}}}; + + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{42}}); + + [[maybe_unused]] std::same_as<zoned_time&> decltype(auto) _ = zt = time_point{duration{99}}; + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == time_point{duration{99}}); + } + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/get_info.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/get_info.pass.cpp new file mode 100644 index 0000000..4bce116 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/get_info.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// sys_info get_info() const; + +#include <cassert> +#include <chrono> +#include <concepts> + +namespace cr = std::chrono; + +int main(int, char**) { + { + cr::zoned_time<cr::seconds> zt; + + std::same_as<cr::sys_info> decltype(auto) info = zt.get_info(); + assert(info.begin == cr::sys_seconds::min()); + assert(info.end == cr::sys_seconds::max()); + assert(info.offset == cr::seconds{0}); + assert(info.save == cr::minutes{0}); + assert(info.abbrev == "UTC"); + } + { + const cr::zoned_time<cr::seconds> zt; + + std::same_as<cr::sys_info> decltype(auto) info = zt.get_info(); + assert(info.begin == cr::sys_seconds::min()); + assert(info.end == cr::sys_seconds::max()); + assert(info.offset == cr::seconds{0}); + assert(info.save == cr::minutes{0}); + assert(info.abbrev == "UTC"); + } + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/get_local_time.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/get_local_time.pass.cpp new file mode 100644 index 0000000..6cad6cf --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/get_local_time.pass.cpp @@ -0,0 +1,133 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// local_time<duration> get_local_time() const; + +#include <chrono> +#include <concepts> + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +static void test_const_member() { + { + using duration = cr::nanoseconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = zt.get_local_time(); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::nanoseconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + const cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = zt.get_local_time(); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } +} + +static void test_duration_conversion() { + // common_type_t<duration, seconds> -> duration + { + using duration = cr::nanoseconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = zt.get_local_time(); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::microseconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = zt.get_local_time(); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::milliseconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = zt.get_local_time(); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + // common_type_t<seconds, seconds> -> seconds + { + using duration = cr::seconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = zt.get_local_time(); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + // common_type_t<duration, seconds> -> seconds + { + using duration = cr::days; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<cr::seconds>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = zt.get_local_time(); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::weeks; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<cr::seconds>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = zt.get_local_time(); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::months; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<cr::seconds>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = zt.get_local_time(); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::years; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<cr::seconds>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = zt.get_local_time(); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } +} + +int main(int, char**) { + test_const_member(); + test_duration_conversion(); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/operator_local_time.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/operator_local_time.pass.cpp new file mode 100644 index 0000000..0e4e47f --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/operator_local_time.pass.cpp @@ -0,0 +1,135 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// explicit operator local_time<duration>() const; + +#include <chrono> +#include <concepts> + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +static void test_const_member() { + { + using duration = cr::nanoseconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + static_assert(!std::is_convertible_v<local_time_point, cr::zoned_time<duration>>); + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = static_cast<local_time_point>(zt); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::nanoseconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + static_assert(!std::is_convertible_v<local_time_point, const cr::zoned_time<duration>>); + const cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = static_cast<local_time_point>(zt); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } +} + +static void test_duration_conversion() { + // common_type_t<duration, seconds> -> duration + { + using duration = cr::nanoseconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = static_cast<local_time_point>(zt); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::microseconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = static_cast<local_time_point>(zt); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::milliseconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = static_cast<local_time_point>(zt); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + // common_type_t<seconds, seconds> -> seconds + { + using duration = cr::seconds; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<duration>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = static_cast<local_time_point>(zt); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + // common_type_t<duration, seconds> -> seconds + { + using duration = cr::days; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<cr::seconds>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = static_cast<local_time_point>(zt); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::weeks; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<cr::seconds>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = static_cast<local_time_point>(zt); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::months; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<cr::seconds>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = static_cast<local_time_point>(zt); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } + { + using duration = cr::years; + using time_point = cr::sys_time<duration>; + using local_time_point = cr::local_time<cr::seconds>; + cr::zoned_time<duration> zt{"Etc/GMT+1", time_point{duration{42}}}; + + std::same_as<local_time_point> decltype(auto) time = static_cast<local_time_point>(zt); + assert(time == local_time_point{duration{42} - cr::hours{1}}); + } +} + +int main(int, char**) { + test_const_member(); + test_duration_conversion(); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/operator_sys_time.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/operator_sys_time.pass.cpp new file mode 100644 index 0000000..327ed49 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.members/operator_sys_time.pass.cpp @@ -0,0 +1,125 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// operator sys_time<duration>() const; + +#include <chrono> +#include <concepts> + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +static void test_const_member() { + { + using duration = cr::nanoseconds; + using time_point = cr::sys_time<duration>; + static_assert(std::is_convertible_v<time_point, cr::zoned_time<duration>>); + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + std::same_as<time_point> decltype(auto) time = static_cast<time_point>(zt); + assert(time == time_point{duration{42}}); + } + { + using duration = cr::nanoseconds; + using time_point = cr::sys_time<duration>; + static_assert(std::is_convertible_v<time_point, const cr::zoned_time<duration>>); + const cr::zoned_time<duration> zt{time_point{duration{42}}}; + + std::same_as<time_point> decltype(auto) time = static_cast<time_point>(zt); + assert(time == time_point{duration{42}}); + } +} + +static void test_duration_conversion() { + // common_type_t<duration, seconds> -> duration + { + using duration = cr::nanoseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + std::same_as<time_point> decltype(auto) time = static_cast<time_point>(zt); + assert(time == time_point{duration{42}}); + } + { + using duration = cr::microseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + std::same_as<time_point> decltype(auto) time = static_cast<time_point>(zt); + assert(time == time_point{duration{42}}); + } + { + using duration = cr::milliseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + std::same_as<time_point> decltype(auto) time = static_cast<time_point>(zt); + assert(time == time_point{duration{42}}); + } + // common_type_t<seconds, seconds> -> seconds + { + using duration = cr::seconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + std::same_as<time_point> decltype(auto) time = static_cast<time_point>(zt); + assert(time == time_point{duration{42}}); + } + // common_type_t<duration, seconds> -> seconds + { + using duration = cr::days; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + std::same_as<cr::sys_seconds> decltype(auto) time = static_cast<cr::sys_seconds>(zt); + assert(time == time_point{duration{42}}); + } + { + using duration = cr::weeks; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + std::same_as<cr::sys_seconds> decltype(auto) time = static_cast<cr::sys_seconds>(zt); + assert(time == time_point{duration{42}}); + } + { + using duration = cr::months; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + std::same_as<cr::sys_seconds> decltype(auto) time = static_cast<cr::sys_seconds>(zt); + assert(time == time_point{duration{42}}); + } + { + using duration = cr::years; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + std::same_as<cr::sys_seconds> decltype(auto) time = static_cast<cr::sys_seconds>(zt); + assert(time == time_point{duration{42}}); + } +} + +int main(int, char**) { + test_const_member(); + test_duration_conversion(); + + return 0; +} |