Path: blob/main/contrib/llvm-project/libcxx/include/__chrono/time_zone.h
35262 views
// -*- C++ -*-1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//89// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html1011#ifndef _LIBCPP___CHRONO_TIME_ZONE_H12#define _LIBCPP___CHRONO_TIME_ZONE_H1314#include <version>15// Enable the contents of the header only when libc++ was built with experimental features enabled.16#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)1718# include <__chrono/calendar.h>19# include <__chrono/duration.h>20# include <__chrono/exception.h>21# include <__chrono/local_info.h>22# include <__chrono/sys_info.h>23# include <__chrono/system_clock.h>24# include <__compare/strong_order.h>25# include <__config>26# include <__memory/unique_ptr.h>27# include <__type_traits/common_type.h>28# include <string_view>2930# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)31# pragma GCC system_header32# endif3334_LIBCPP_PUSH_MACROS35# include <__undef_macros>3637_LIBCPP_BEGIN_NAMESPACE_STD3839# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \40!defined(_LIBCPP_HAS_NO_LOCALIZATION)4142namespace chrono {4344enum class choose { earliest, latest };4546class _LIBCPP_AVAILABILITY_TZDB time_zone {47_LIBCPP_HIDE_FROM_ABI time_zone() = default;4849public:50class __impl; // public so it can be used by make_unique.5152// The "constructor".53//54// The default constructor is private to avoid the constructor from being55// part of the ABI. Instead use an __ugly_named function as an ABI interface,56// since that gives us the ability to change it in the future.57[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI static time_zone __create(unique_ptr<__impl>&& __p);5859_LIBCPP_EXPORTED_FROM_ABI ~time_zone();6061_LIBCPP_HIDE_FROM_ABI time_zone(time_zone&&) = default;62_LIBCPP_HIDE_FROM_ABI time_zone& operator=(time_zone&&) = default;6364[[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name(); }6566template <class _Duration>67[[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_info get_info(const sys_time<_Duration>& __time) const {68return __get_info(chrono::time_point_cast<seconds>(__time));69}7071template <class _Duration>72[[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_info get_info(const local_time<_Duration>& __time) const {73return __get_info(chrono::time_point_cast<seconds>(__time));74}7576// We don't apply nodiscard here since this function throws on many inputs,77// so it could be used as a validation.78template <class _Duration>79_LIBCPP_HIDE_FROM_ABI sys_time<common_type_t<_Duration, seconds>> to_sys(const local_time<_Duration>& __time) const {80local_info __info = get_info(__time);81switch (__info.result) {82case local_info::unique:83return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};8485case local_info::nonexistent:86chrono::__throw_nonexistent_local_time(__time, __info);8788case local_info::ambiguous:89chrono::__throw_ambiguous_local_time(__time, __info);90}9192// TODO TZDB The Standard does not specify anything in these cases.93_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(94__info.result != -1, "cannot convert the local time; it would be before the minimum system clock value");95_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(96__info.result != -2, "cannot convert the local time; it would be after the maximum system clock value");9798return {};99}100101template <class _Duration>102[[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_time<common_type_t<_Duration, seconds>>103to_sys(const local_time<_Duration>& __time, choose __z) const {104local_info __info = get_info(__time);105switch (__info.result) {106case local_info::unique:107case local_info::nonexistent: // first and second are the same108return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};109110case local_info::ambiguous:111switch (__z) {112case choose::earliest:113return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};114115case choose::latest:116return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.second.offset};117118// Note a value out of bounds is not specified.119}120}121122// TODO TZDB The standard does not specify anything in these cases.123_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(124__info.result != -1, "cannot convert the local time; it would be before the minimum system clock value");125_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(126__info.result != -2, "cannot convert the local time; it would be after the maximum system clock value");127128return {};129}130131template <class _Duration>132[[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_time<common_type_t<_Duration, seconds>>133to_local(const sys_time<_Duration>& __time) const {134using _Dp = common_type_t<_Duration, seconds>;135136sys_info __info = get_info(__time);137138_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(139__info.offset >= chrono::seconds{0} || __time.time_since_epoch() >= _Dp::min() - __info.offset,140"cannot convert the system time; it would be before the minimum local clock value");141142_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(143__info.offset <= chrono::seconds{0} || __time.time_since_epoch() <= _Dp::max() - __info.offset,144"cannot convert the system time; it would be after the maximum local clock value");145146return local_time<_Dp>{__time.time_since_epoch() + __info.offset};147}148149[[nodiscard]] _LIBCPP_HIDE_FROM_ABI const __impl& __implementation() const noexcept { return *__impl_; }150151private:152[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string_view __name() const noexcept;153154[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI sys_info __get_info(sys_seconds __time) const;155[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI local_info __get_info(local_seconds __time) const;156157unique_ptr<__impl> __impl_;158};159160[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool161operator==(const time_zone& __x, const time_zone& __y) noexcept {162return __x.name() == __y.name();163}164165[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering166operator<=>(const time_zone& __x, const time_zone& __y) noexcept {167return __x.name() <=> __y.name();168}169170} // namespace chrono171172# endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)173// && !defined(_LIBCPP_HAS_NO_LOCALIZATION)174175_LIBCPP_END_NAMESPACE_STD176177_LIBCPP_POP_MACROS178179#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)180181#endif // _LIBCPP___CHRONO_TIME_ZONE_H182183184