[libcxx-commits] [libcxx] [libc++][chrono] P2592R3: Hashing for chrono (PR #165132)

Rafail Shakhin ogly via libcxx-commits libcxx-commits at lists.llvm.org
Mon Oct 27 09:03:36 PDT 2025


https://github.com/rsaddatimov updated https://github.com/llvm/llvm-project/pull/165132

>From 76e6a5cc0e1f0d9a2f7e6cf07d46ebbfc869a936 Mon Sep 17 00:00:00 2001
From: Rafail <rafa.saddatimov at gmail.com>
Date: Sun, 26 Oct 2025 08:26:14 +0300
Subject: [PATCH 1/7] Initial hashing support for chrono

---
 libcxx/docs/FeatureTestMacroTable.rst         |  2 +-
 libcxx/docs/ReleaseNotes/22.rst               |  1 +
 libcxx/docs/Status/Cxx2cPapers.csv            |  2 +-
 libcxx/include/__chrono/day.h                 |  8 +++
 libcxx/include/__chrono/duration.h            | 13 +++++
 libcxx/include/__chrono/leap_second.h         |  8 +++
 libcxx/include/__chrono/month.h               |  8 +++
 libcxx/include/__chrono/month_weekday.h       | 15 +++++
 libcxx/include/__chrono/monthday.h            | 15 +++++
 libcxx/include/__chrono/time_point.h          | 14 +++++
 libcxx/include/__chrono/weekday.h             | 22 ++++++++
 libcxx/include/__chrono/year.h                |  8 +++
 libcxx/include/__chrono/year_month.h          |  8 +++
 libcxx/include/__chrono/year_month_day.h      | 15 +++++
 libcxx/include/__chrono/year_month_weekday.h  | 17 ++++++
 libcxx/include/__chrono/zoned_time.h          | 10 ++++
 libcxx/include/version                        |  4 +-
 .../time/time.hash/time.hash_enabled.pass.cpp | 55 +++++++++++++++++++
 18 files changed, 221 insertions(+), 4 deletions(-)
 create mode 100644 libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 8fba6db871f08..a878c46d35cbe 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -88,7 +88,7 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_byte``                                         ``201603L``
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_chrono``                                       ``201611L``
+    ``__cpp_lib_chrono``                                       ``202510L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_clamp``                                        ``201603L``
     ---------------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index 25d33a9c2eb50..7ea3529642c90 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -38,6 +38,7 @@ What's New in Libc++ 22.0.0?
 Implemented Papers
 ------------------
 
+- P2592R3: Hashing support for ``std::chrono`` value classes (`Github <https://llvm.org/PR105358>`__)
 - P2321R2: ``zip`` (`Github <https://llvm.org/PR105169>`__) (The paper is partially implemented. ``zip_transform_view``
   is implemented in this release)
 - P3044R2: sub-``string_view`` from ``string`` (`Github <https://llvm.org/PR148140>`__)
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index a5423acf0d419..493e6a3c9ed44 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -1,6 +1,6 @@
 "Paper #","Paper Name","Meeting","Status","First released version","GitHub issue","Notes"
 "`P2497R0 <https://wg21.link/P2497R0>`__","Testing for success or failure of ``<charconv>`` functions","2023-06 (Varna)","|Complete|","18","`#105357 <https://github.com/llvm/llvm-project/issues/105357>`__",""
-"`P2592R3 <https://wg21.link/P2592R3>`__","Hashing support for ``std::chrono`` value classes","2023-06 (Varna)","","","`#105358 <https://github.com/llvm/llvm-project/issues/105358>`__",""
+"`P2592R3 <https://wg21.link/P2592R3>`__","Hashing support for ``std::chrono`` value classes","2023-06 (Varna)","|Complete|","22","`#105358 <https://github.com/llvm/llvm-project/issues/105358>`__",""
 "`P2587R3 <https://wg21.link/P2587R3>`__","``to_string`` or not ``to_string``","2023-06 (Varna)","","","`#105359 <https://github.com/llvm/llvm-project/issues/105359>`__",""
 "`P2562R1 <https://wg21.link/P2562R1>`__","``constexpr`` Stable Sorting","2023-06 (Varna)","|Complete|","21","`#105360 <https://github.com/llvm/llvm-project/issues/105360>`__",""
 "`P2545R4 <https://wg21.link/P2545R4>`__","Read-Copy Update (RCU)","2023-06 (Varna)","","","`#105361 <https://github.com/llvm/llvm-project/issues/105361>`__",""
diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h
index f5b14689a78ac..5c39bf16f72ea 100644
--- a/libcxx/include/__chrono/day.h
+++ b/libcxx/include/__chrono/day.h
@@ -13,6 +13,7 @@
 #include <__chrono/duration.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -92,6 +93,13 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) no
 
 } // namespace chrono
 
+template <>
+struct hash<chrono::day> : public __unary_function<chrono::day, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::day& __d) const _NOEXCEPT {
+    return hash<unsigned>{}(static_cast<unsigned>(__d));
+  }
+};
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h
index 57fa64d650068..3e04891f5b0c6 100644
--- a/libcxx/include/__chrono/duration.h
+++ b/libcxx/include/__chrono/duration.h
@@ -13,6 +13,7 @@
 #include <__compare/ordering.h>
 #include <__compare/three_way_comparable.h>
 #include <__config>
+#include <__functional/hash.h>
 #include <__type_traits/common_type.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_convertible.h>
@@ -538,6 +539,18 @@ using namespace literals::chrono_literals;
 
 #endif // _LIBCPP_STD_VER >= 14
 
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Rep, class _Period>
+  requires __has_enabled_hash<_Rep>::value
+struct hash<chrono::duration<_Rep, _Period>> : public __unary_function<chrono::duration<_Rep, _Period>, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::duration<_Rep, _Period>& __d) const {
+    return hash<_Rep>{}(__d.count());
+  }
+};
+
+#endif // _LIBCPP_STD_VER >= 20
+
 _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
diff --git a/libcxx/include/__chrono/leap_second.h b/libcxx/include/__chrono/leap_second.h
index 1857bef80376e..cf7a2c16626d0 100644
--- a/libcxx/include/__chrono/leap_second.h
+++ b/libcxx/include/__chrono/leap_second.h
@@ -22,6 +22,7 @@
 #  include <__compare/ordering.h>
 #  include <__compare/three_way_comparable.h>
 #  include <__config>
+#  include <__functional/hash.h>
 #  include <__utility/private_constructor_tag.h>
 
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -122,6 +123,13 @@ class leap_second {
 
 } // namespace chrono
 
+template <>
+struct hash<chrono::leap_second> : public __unary_function<chrono::leap_second, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::leap_second& __lp) const _NOEXCEPT {
+    return hash<chrono::seconds>{}(__lp.value());
+  }
+};
+
 #  endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__chrono/month.h b/libcxx/include/__chrono/month.h
index 77c67d0954efa..d76efd4973193 100644
--- a/libcxx/include/__chrono/month.h
+++ b/libcxx/include/__chrono/month.h
@@ -13,6 +13,7 @@
 #include <__chrono/duration.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -108,6 +109,13 @@ inline constexpr month December{12};
 
 } // namespace chrono
 
+template <>
+struct hash<chrono::month> : public __unary_function<chrono::month, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month& __m) const _NOEXCEPT {
+    return hash<unsigned>{}(static_cast<unsigned>(__m));
+  }
+};
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/month_weekday.h b/libcxx/include/__chrono/month_weekday.h
index 7919879655214..a46526eca2853 100644
--- a/libcxx/include/__chrono/month_weekday.h
+++ b/libcxx/include/__chrono/month_weekday.h
@@ -13,6 +13,7 @@
 #include <__chrono/month.h>
 #include <__chrono/weekday.h>
 #include <__config>
+#include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -98,6 +99,20 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(const weekda
 }
 } // namespace chrono
 
+template <>
+struct hash<chrono::month_weekday> : public __unary_function<chrono::month_weekday, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday& __mw) const _NOEXCEPT {
+    return hash<chrono::month>{}(__mw.month()) ^ hash<chrono::weekday_indexed>{}(__mw.weekday_indexed());
+  }
+};
+
+template <>
+struct hash<chrono::month_weekday_last> : public __unary_function<chrono::month_weekday_last, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday_last& __mwl) const _NOEXCEPT {
+    return hash<chrono::month>{}(__mwl.month()) ^ hash<chrono::weekday_last>{}(__mwl.weekday_last());
+  }
+};
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/monthday.h b/libcxx/include/__chrono/monthday.h
index 57712cf0b65a8..79c2a4c9f0a42 100644
--- a/libcxx/include/__chrono/monthday.h
+++ b/libcxx/include/__chrono/monthday.h
@@ -15,6 +15,7 @@
 #include <__chrono/month.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -126,6 +127,20 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, int _
 
 } // namespace chrono
 
+template <>
+struct hash<chrono::month_day> : public __unary_function<chrono::month_day, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day& __md) const _NOEXCEPT {
+    return hash<chrono::month>{}(__md.month()) ^ hash<chrono::day>{}(__md.day());
+  }
+};
+
+template <>
+struct hash<chrono::month_day_last> : public __unary_function<chrono::month_day_last, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day_last& __mdl) const _NOEXCEPT {
+    return hash<chrono::month>{}(__mdl.month());
+  }
+};
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h
index bc2c7798a630b..02720ec66228e 100644
--- a/libcxx/include/__chrono/time_point.h
+++ b/libcxx/include/__chrono/time_point.h
@@ -14,6 +14,7 @@
 #include <__compare/ordering.h>
 #include <__compare/three_way_comparable.h>
 #include <__config>
+#include <__functional/hash.h>
 #include <__type_traits/common_type.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_convertible.h>
@@ -224,6 +225,19 @@ operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock,
 
 } // namespace chrono
 
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Clock, class _Duration>
+  requires __has_enabled_hash<_Duration>::value
+struct hash<chrono::time_point<_Clock, _Duration>>
+    : public __unary_function<chrono::time_point<_Clock, _Duration>, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::time_point<_Clock, _Duration>& __tp) const {
+    return hash<_Duration>{}(__tp.time_since_epoch());
+  }
+};
+
+#endif // _LIBCPP_STD_VER >= 20
+
 _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
diff --git a/libcxx/include/__chrono/weekday.h b/libcxx/include/__chrono/weekday.h
index 728cbb844633f..2fc988a9f4b57 100644
--- a/libcxx/include/__chrono/weekday.h
+++ b/libcxx/include/__chrono/weekday.h
@@ -15,6 +15,7 @@
 #include <__chrono/system_clock.h>
 #include <__chrono/time_point.h>
 #include <__config>
+#include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -160,6 +161,27 @@ inline constexpr weekday Saturday{6};
 
 } // namespace chrono
 
+template <>
+struct hash<chrono::weekday> : public __unary_function<chrono::weekday, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday& __w) const _NOEXCEPT {
+    return hash<unsigned>{}(__w.c_encoding());
+  }
+};
+
+template <>
+struct hash<chrono::weekday_indexed> : public __unary_function<chrono::weekday_indexed, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday_indexed& __wi) const _NOEXCEPT {
+    return hash<chrono::weekday>{}(__wi.weekday()) ^ hash<unsigned>{}(__wi.index());
+  }
+};
+
+template <>
+struct hash<chrono::weekday_last> : public __unary_function<chrono::weekday_last, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday_last& __wl) const _NOEXCEPT {
+    return hash<chrono::weekday>{}(__wl.weekday());
+  }
+};
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h
index 2ae5180cb8fc9..4ee4186dcf533 100644
--- a/libcxx/include/__chrono/year.h
+++ b/libcxx/include/__chrono/year.h
@@ -13,6 +13,7 @@
 #include <__chrono/duration.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__functional/hash.h>
 #include <limits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -109,6 +110,13 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept {
 
 } // namespace chrono
 
+template <>
+struct hash<chrono::year> : public __unary_function<chrono::year, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year& __y) const _NOEXCEPT {
+    return hash<int>{}(static_cast<int>(__y));
+  }
+};
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/year_month.h b/libcxx/include/__chrono/year_month.h
index cf9234bdb4625..a3e1429527bea 100644
--- a/libcxx/include/__chrono/year_month.h
+++ b/libcxx/include/__chrono/year_month.h
@@ -15,6 +15,7 @@
 #include <__chrono/year.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -116,6 +117,13 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const
 
 } // namespace chrono
 
+template <>
+struct hash<chrono::year_month> : public __unary_function<chrono::year_month, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month& __ym) const _NOEXCEPT {
+    return hash<chrono::year>{}(__ym.year()) ^ hash<chrono::month>{}(__ym.month());
+  }
+};
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/year_month_day.h b/libcxx/include/__chrono/year_month_day.h
index a0510a14f4ede..b0c05716bdba3 100644
--- a/libcxx/include/__chrono/year_month_day.h
+++ b/libcxx/include/__chrono/year_month_day.h
@@ -21,6 +21,7 @@
 #include <__chrono/year_month.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__functional/hash.h>
 #include <limits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -330,6 +331,20 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool year_month_day::ok() const noexcept
 
 } // namespace chrono
 
+template <>
+struct hash<chrono::year_month_day> : public __unary_function<chrono::year_month_day, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_day& __ymd) const _NOEXCEPT {
+    return hash<chrono::year>{}(__ymd.year()) ^ hash<chrono::month>{}(__ymd.month()) ^ hash<chrono::day>{}(__ymd.day());
+  }
+};
+
+template <>
+struct hash<chrono::year_month_day_last> : public __unary_function<chrono::year_month_day_last, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_day_last& __ymdl) const _NOEXCEPT {
+    return hash<chrono::year>{}(__ymdl.year()) ^ hash<chrono::month_day_last>{}(__ymdl.month_day_last());
+  }
+};
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/year_month_weekday.h b/libcxx/include/__chrono/year_month_weekday.h
index 0c3dd494c8787..6ae704c397b97 100644
--- a/libcxx/include/__chrono/year_month_weekday.h
+++ b/libcxx/include/__chrono/year_month_weekday.h
@@ -22,6 +22,7 @@
 #include <__chrono/year_month.h>
 #include <__chrono/year_month_day.h>
 #include <__config>
+#include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -280,6 +281,22 @@ year_month_weekday_last::operator-=(const years& __dy) noexcept {
 
 } // namespace chrono
 
+template <>
+struct hash<chrono::year_month_weekday> : public __unary_function<chrono::year_month_weekday, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_weekday& __ymw) const _NOEXCEPT {
+    return hash<chrono::year>{}(__ymw.year()) ^ hash<chrono::month>{}(__ymw.month()) ^
+           hash<chrono::weekday_indexed>{}(__ymw.weekday_indexed());
+  }
+};
+
+template <>
+struct hash<chrono::year_month_weekday_last> : public __unary_function<chrono::year_month_weekday_last, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_weekday_last& __ymwl) const _NOEXCEPT {
+    return hash<chrono::year>{}(__ymwl.year()) ^ hash<chrono::month>{}(__ymwl.month()) ^
+           hash<chrono::weekday_last>{}(__ymwl.weekday_last());
+  }
+};
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h
index 8db687a422ab1..5f110d1721502 100644
--- a/libcxx/include/__chrono/zoned_time.h
+++ b/libcxx/include/__chrono/zoned_time.h
@@ -24,6 +24,7 @@
 #  include <__chrono/tzdb_list.h>
 #  include <__concepts/constructible.h>
 #  include <__config>
+#  include <__functional/hash.h>
 #  include <__type_traits/common_type.h>
 #  include <__type_traits/conditional.h>
 #  include <__type_traits/remove_cvref.h>
@@ -216,6 +217,15 @@ operator==(const zoned_time<_Duration1, _TimeZonePtr>& __lhs, const zoned_time<_
 
 } // namespace chrono
 
+template <class _Duration, class _TimeZonePtr>
+  requires __has_enabled_hash<_Duration>::value && __has_enabled_hash<_TimeZonePtr>::value
+struct hash<chrono::zoned_time<_Duration, _TimeZonePtr>>
+    : public __unary_function<chrono::zoned_time<_Duration, _TimeZonePtr>, size_t> {
+  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::zoned_time<_Duration, _TimeZonePtr>& __zt) const {
+    return hash<chrono::sys_time<_Duration>>{}(__zt.get_sys_time()) ^ hash<_TimeZonePtr>{}(__zt.get_time_zone());
+  }
+};
+
 #  endif // _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM &&
          // _LIBCPP_HAS_LOCALIZATION
 
diff --git a/libcxx/include/version b/libcxx/include/version
index 0fef1bb87cf60..5200d72ed1ea5 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -57,7 +57,7 @@ __cpp_lib_byteswap                                      202110L <bit>
 __cpp_lib_char8_t                                       201907L <atomic> <filesystem> <istream>
                                                                 <limits> <locale> <ostream>
                                                                 <string> <string_view>
-__cpp_lib_chrono                                        201611L <chrono>
+__cpp_lib_chrono                                        202510L <chrono>
 __cpp_lib_chrono_udls                                   201304L <chrono>
 __cpp_lib_clamp                                         201603L <algorithm>
 __cpp_lib_common_reference                              202302L <type_traits>
@@ -332,7 +332,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_bool_constant                        201505L
 # define __cpp_lib_boyer_moore_searcher                 201603L
 # define __cpp_lib_byte                                 201603L
-# define __cpp_lib_chrono                               201611L
+# define __cpp_lib_chrono                               202510L
 # define __cpp_lib_clamp                                201603L
 # define __cpp_lib_enable_shared_from_this              201603L
 // # define __cpp_lib_execution                            201603L
diff --git a/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp b/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp
new file mode 100644
index 0000000000000..e935a121c0ab0
--- /dev/null
+++ b/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <chrono>
+
+// Test that <chrono> provides all of the hash specializations.
+
+#include <chrono>
+#include "poisoned_hash_helper.h"
+namespace chrono = std::chrono;
+
+int main(int, char**) {
+  test_hash_enabled<chrono::nanoseconds>();
+  test_hash_enabled<chrono::microseconds>();
+  test_hash_enabled<chrono::milliseconds>();
+  test_hash_enabled<chrono::seconds>();
+  test_hash_enabled<chrono::minutes>();
+  test_hash_enabled<chrono::hours>();
+  test_hash_enabled<chrono::days>();
+  test_hash_enabled<chrono::weeks>();
+  test_hash_enabled<chrono::months>();
+  test_hash_enabled<chrono::years>();
+
+  test_hash_enabled<chrono::day>();
+  test_hash_enabled<chrono::month>();
+  test_hash_enabled<chrono::year>();
+
+  test_hash_enabled<chrono::weekday>();
+  test_hash_enabled<chrono::weekday_indexed>();
+  test_hash_enabled(chrono::weekday_last(chrono::weekday{}));
+
+  test_hash_enabled<chrono::month_day>();
+  test_hash_enabled(chrono::month_day_last(chrono::month{}));
+
+  test_hash_enabled(chrono::month_weekday(chrono::month{}, chrono::weekday_indexed{}));
+  test_hash_enabled(chrono::month_weekday_last(chrono::month{}, chrono::weekday_last(chrono::weekday{})));
+
+  test_hash_enabled<chrono::year_month>();
+
+  test_hash_enabled<chrono::year_month_day>();
+  test_hash_enabled(chrono::year_month_day_last(chrono::year{}, chrono::month_day_last(chrono::month{})));
+
+  test_hash_enabled<chrono::year_month_weekday>();
+  test_hash_enabled(
+      chrono::year_month_weekday_last(chrono::year{}, chrono::month{}, chrono::weekday_last(chrono::weekday{})));
+
+  return 0;
+}

>From d346b34a71bdd17e0e95c7893064adab89fbbc37 Mon Sep 17 00:00:00 2001
From: Rafail <rafa.saddatimov at gmail.com>
Date: Sun, 26 Oct 2025 17:51:01 +0300
Subject: [PATCH 2/7] Update version via script

---
 libcxx/docs/FeatureTestMacroTable.rst                      | 4 +++-
 libcxx/include/version                                     | 7 +++++--
 .../support.limits.general/chrono.version.compile.pass.cpp | 4 ++--
 .../version.version.compile.pass.cpp                       | 4 ++--
 libcxx/utils/generate_feature_test_macro_components.py     | 2 +-
 5 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index a878c46d35cbe..51c2c720cdf9a 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -88,7 +88,7 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_byte``                                         ``201603L``
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_chrono``                                       ``202510L``
+    ``__cpp_lib_chrono``                                       ``201611L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_clamp``                                        ``201603L``
     ---------------------------------------------------------- -----------------
@@ -424,6 +424,8 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_bitset``                                       ``202306L``
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_chrono``                                       ``202306L``
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_algorithms``                         ``202306L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_forward_list``                       ``202502L``
diff --git a/libcxx/include/version b/libcxx/include/version
index 5200d72ed1ea5..07cc828bd7c53 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -57,7 +57,8 @@ __cpp_lib_byteswap                                      202110L <bit>
 __cpp_lib_char8_t                                       201907L <atomic> <filesystem> <istream>
                                                                 <limits> <locale> <ostream>
                                                                 <string> <string_view>
-__cpp_lib_chrono                                        202510L <chrono>
+__cpp_lib_chrono                                        202306L <chrono>
+                                                        201611L // C++17
 __cpp_lib_chrono_udls                                   201304L <chrono>
 __cpp_lib_clamp                                         201603L <algorithm>
 __cpp_lib_common_reference                              202302L <type_traits>
@@ -332,7 +333,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_bool_constant                        201505L
 # define __cpp_lib_boyer_moore_searcher                 201603L
 # define __cpp_lib_byte                                 201603L
-# define __cpp_lib_chrono                               202510L
+# define __cpp_lib_chrono                               201611L
 # define __cpp_lib_clamp                                201603L
 # define __cpp_lib_enable_shared_from_this              201603L
 // # define __cpp_lib_execution                            201603L
@@ -550,6 +551,8 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # undef  __cpp_lib_bind_front
 # define __cpp_lib_bind_front                           202306L
 # define __cpp_lib_bitset                               202306L
+# undef  __cpp_lib_chrono
+# define __cpp_lib_chrono                               202306L
 # undef  __cpp_lib_constexpr_algorithms
 # define __cpp_lib_constexpr_algorithms                 202306L
 # define __cpp_lib_constexpr_forward_list               202502L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp
index d5d7a5da4a64d..98b3eda149342 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp
@@ -94,8 +94,8 @@
 #  ifndef __cpp_lib_chrono
 #    error "__cpp_lib_chrono should be defined in c++26"
 #  endif
-#  if __cpp_lib_chrono != 201611L
-#    error "__cpp_lib_chrono should have the value 201611L in c++26"
+#  if __cpp_lib_chrono != 202306L
+#    error "__cpp_lib_chrono should have the value 202306L in c++26"
 #  endif
 
 #  ifndef __cpp_lib_chrono_udls
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 05af1fb0cf14b..1ecba19d39abe 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -6455,8 +6455,8 @@
 #  ifndef __cpp_lib_chrono
 #    error "__cpp_lib_chrono should be defined in c++26"
 #  endif
-#  if __cpp_lib_chrono != 201611L
-#    error "__cpp_lib_chrono should have the value 201611L in c++26"
+#  if __cpp_lib_chrono != 202306L
+#    error "__cpp_lib_chrono should have the value 202306L in c++26"
 #  endif
 
 #  ifndef __cpp_lib_chrono_udls
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index f6f252751b3e3..114f844cc238e 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -300,7 +300,7 @@ def add_version_header(tc):
             "name": "__cpp_lib_chrono",
             "values": {
                 "c++17": 201611,
-                # "c++26": 202306, # P2592R3 Hashing support for std::chrono value classes
+                "c++26": 202306, # P2592R3 Hashing support for std::chrono value classes
             },
             "headers": ["chrono"],
         },

>From 236fa22874708dfc4012d1031c9a8fa4563515c7 Mon Sep 17 00:00:00 2001
From: Rafail <rafa.saddatimov at gmail.com>
Date: Sun, 26 Oct 2025 18:11:57 +0300
Subject: [PATCH 3/7] Wrap around c++26 macro and test fix

---
 libcxx/include/__chrono/day.h                 |  4 ++
 libcxx/include/__chrono/duration.h            |  4 +-
 libcxx/include/__chrono/leap_second.h         |  4 ++
 libcxx/include/__chrono/month.h               |  4 ++
 libcxx/include/__chrono/month_weekday.h       |  4 ++
 libcxx/include/__chrono/monthday.h            |  4 ++
 libcxx/include/__chrono/time_point.h          |  4 +-
 libcxx/include/__chrono/weekday.h             |  4 ++
 libcxx/include/__chrono/year.h                |  4 ++
 libcxx/include/__chrono/year_month.h          |  4 ++
 libcxx/include/__chrono/year_month_day.h      |  4 ++
 libcxx/include/__chrono/year_month_weekday.h  |  4 ++
 libcxx/include/__chrono/zoned_time.h          |  4 ++
 .../time/time.hash/time.hash_enabled.pass.cpp | 62 ++++++++++---------
 14 files changed, 82 insertions(+), 32 deletions(-)

diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h
index 5c39bf16f72ea..2478f25214912 100644
--- a/libcxx/include/__chrono/day.h
+++ b/libcxx/include/__chrono/day.h
@@ -93,6 +93,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) no
 
 } // namespace chrono
 
+#  if _LIBCPP_STD_VER >= 26
+
 template <>
 struct hash<chrono::day> : public __unary_function<chrono::day, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::day& __d) const _NOEXCEPT {
@@ -100,6 +102,8 @@ struct hash<chrono::day> : public __unary_function<chrono::day, size_t> {
   }
 };
 
+#  endif // _LIBCPP_STD_VER >= 26
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h
index 3e04891f5b0c6..c92ab4a5ffddf 100644
--- a/libcxx/include/__chrono/duration.h
+++ b/libcxx/include/__chrono/duration.h
@@ -539,7 +539,7 @@ using namespace literals::chrono_literals;
 
 #endif // _LIBCPP_STD_VER >= 14
 
-#if _LIBCPP_STD_VER >= 20
+#if _LIBCPP_STD_VER >= 26
 
 template <class _Rep, class _Period>
   requires __has_enabled_hash<_Rep>::value
@@ -549,7 +549,7 @@ struct hash<chrono::duration<_Rep, _Period>> : public __unary_function<chrono::d
   }
 };
 
-#endif // _LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 26
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/libcxx/include/__chrono/leap_second.h b/libcxx/include/__chrono/leap_second.h
index cf7a2c16626d0..8d3eafbde4639 100644
--- a/libcxx/include/__chrono/leap_second.h
+++ b/libcxx/include/__chrono/leap_second.h
@@ -123,6 +123,8 @@ class leap_second {
 
 } // namespace chrono
 
+#    if _LIBCPP_STD_VER >= 26
+
 template <>
 struct hash<chrono::leap_second> : public __unary_function<chrono::leap_second, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::leap_second& __lp) const _NOEXCEPT {
@@ -130,6 +132,8 @@ struct hash<chrono::leap_second> : public __unary_function<chrono::leap_second,
   }
 };
 
+#    endif // _LIBCPP_STD_VER >= 26
+
 #  endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__chrono/month.h b/libcxx/include/__chrono/month.h
index d76efd4973193..470451e8153fe 100644
--- a/libcxx/include/__chrono/month.h
+++ b/libcxx/include/__chrono/month.h
@@ -109,6 +109,8 @@ inline constexpr month December{12};
 
 } // namespace chrono
 
+#  if _LIBCPP_STD_VER >= 26
+
 template <>
 struct hash<chrono::month> : public __unary_function<chrono::month, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month& __m) const _NOEXCEPT {
@@ -116,6 +118,8 @@ struct hash<chrono::month> : public __unary_function<chrono::month, size_t> {
   }
 };
 
+#  endif // _LIBCPP_STD_VER >= 26
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/month_weekday.h b/libcxx/include/__chrono/month_weekday.h
index a46526eca2853..58ef6b8540351 100644
--- a/libcxx/include/__chrono/month_weekday.h
+++ b/libcxx/include/__chrono/month_weekday.h
@@ -99,6 +99,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(const weekda
 }
 } // namespace chrono
 
+#  if _LIBCPP_STD_VER >= 26
+
 template <>
 struct hash<chrono::month_weekday> : public __unary_function<chrono::month_weekday, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday& __mw) const _NOEXCEPT {
@@ -113,6 +115,8 @@ struct hash<chrono::month_weekday_last> : public __unary_function<chrono::month_
   }
 };
 
+#  endif // _LIBCPP_STD_VER >= 26
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/monthday.h b/libcxx/include/__chrono/monthday.h
index 79c2a4c9f0a42..961c131854e9b 100644
--- a/libcxx/include/__chrono/monthday.h
+++ b/libcxx/include/__chrono/monthday.h
@@ -127,6 +127,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, int _
 
 } // namespace chrono
 
+#  if _LIBCPP_STD_VER >= 26
+
 template <>
 struct hash<chrono::month_day> : public __unary_function<chrono::month_day, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day& __md) const _NOEXCEPT {
@@ -141,6 +143,8 @@ struct hash<chrono::month_day_last> : public __unary_function<chrono::month_day_
   }
 };
 
+#  endif // _LIBCPP_STD_VER >= 26
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h
index 02720ec66228e..85a91e9b35895 100644
--- a/libcxx/include/__chrono/time_point.h
+++ b/libcxx/include/__chrono/time_point.h
@@ -225,7 +225,7 @@ operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock,
 
 } // namespace chrono
 
-#if _LIBCPP_STD_VER >= 20
+#if _LIBCPP_STD_VER >= 26
 
 template <class _Clock, class _Duration>
   requires __has_enabled_hash<_Duration>::value
@@ -236,7 +236,7 @@ struct hash<chrono::time_point<_Clock, _Duration>>
   }
 };
 
-#endif // _LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 26
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/libcxx/include/__chrono/weekday.h b/libcxx/include/__chrono/weekday.h
index 2fc988a9f4b57..3842f44f3bf9f 100644
--- a/libcxx/include/__chrono/weekday.h
+++ b/libcxx/include/__chrono/weekday.h
@@ -161,6 +161,8 @@ inline constexpr weekday Saturday{6};
 
 } // namespace chrono
 
+#  if _LIBCPP_STD_VER >= 26
+
 template <>
 struct hash<chrono::weekday> : public __unary_function<chrono::weekday, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday& __w) const _NOEXCEPT {
@@ -182,6 +184,8 @@ struct hash<chrono::weekday_last> : public __unary_function<chrono::weekday_last
   }
 };
 
+#  endif // _LIBCPP_STD_VER >= 26
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h
index 4ee4186dcf533..e2f8985732d4d 100644
--- a/libcxx/include/__chrono/year.h
+++ b/libcxx/include/__chrono/year.h
@@ -110,6 +110,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept {
 
 } // namespace chrono
 
+#  if _LIBCPP_STD_VER >= 26
+
 template <>
 struct hash<chrono::year> : public __unary_function<chrono::year, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year& __y) const _NOEXCEPT {
@@ -117,6 +119,8 @@ struct hash<chrono::year> : public __unary_function<chrono::year, size_t> {
   }
 };
 
+#  endif // _LIBCPP_STD_VER >= 26
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/year_month.h b/libcxx/include/__chrono/year_month.h
index a3e1429527bea..6d6b14d952982 100644
--- a/libcxx/include/__chrono/year_month.h
+++ b/libcxx/include/__chrono/year_month.h
@@ -117,6 +117,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const
 
 } // namespace chrono
 
+#  if _LIBCPP_STD_VER >= 26
+
 template <>
 struct hash<chrono::year_month> : public __unary_function<chrono::year_month, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month& __ym) const _NOEXCEPT {
@@ -124,6 +126,8 @@ struct hash<chrono::year_month> : public __unary_function<chrono::year_month, si
   }
 };
 
+#  endif // _LIBCPP_STD_VER >= 26
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/year_month_day.h b/libcxx/include/__chrono/year_month_day.h
index b0c05716bdba3..c1661a1b7614b 100644
--- a/libcxx/include/__chrono/year_month_day.h
+++ b/libcxx/include/__chrono/year_month_day.h
@@ -331,6 +331,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool year_month_day::ok() const noexcept
 
 } // namespace chrono
 
+#  if _LIBCPP_STD_VER >= 26
+
 template <>
 struct hash<chrono::year_month_day> : public __unary_function<chrono::year_month_day, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_day& __ymd) const _NOEXCEPT {
@@ -345,6 +347,8 @@ struct hash<chrono::year_month_day_last> : public __unary_function<chrono::year_
   }
 };
 
+#  endif // _LIBCPP_STD_VER >= 26
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/year_month_weekday.h b/libcxx/include/__chrono/year_month_weekday.h
index 6ae704c397b97..ae7e21747d2a4 100644
--- a/libcxx/include/__chrono/year_month_weekday.h
+++ b/libcxx/include/__chrono/year_month_weekday.h
@@ -281,6 +281,8 @@ year_month_weekday_last::operator-=(const years& __dy) noexcept {
 
 } // namespace chrono
 
+#  if _LIBCPP_STD_VER >= 26
+
 template <>
 struct hash<chrono::year_month_weekday> : public __unary_function<chrono::year_month_weekday, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_weekday& __ymw) const _NOEXCEPT {
@@ -297,6 +299,8 @@ struct hash<chrono::year_month_weekday_last> : public __unary_function<chrono::y
   }
 };
 
+#  endif // _LIBCPP_STD_VER >= 26
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h
index 5f110d1721502..595d0ce4d3d1c 100644
--- a/libcxx/include/__chrono/zoned_time.h
+++ b/libcxx/include/__chrono/zoned_time.h
@@ -217,6 +217,8 @@ operator==(const zoned_time<_Duration1, _TimeZonePtr>& __lhs, const zoned_time<_
 
 } // namespace chrono
 
+#    if _LIBCPP_STD_VER >= 26
+
 template <class _Duration, class _TimeZonePtr>
   requires __has_enabled_hash<_Duration>::value && __has_enabled_hash<_TimeZonePtr>::value
 struct hash<chrono::zoned_time<_Duration, _TimeZonePtr>>
@@ -226,6 +228,8 @@ struct hash<chrono::zoned_time<_Duration, _TimeZonePtr>>
   }
 };
 
+#    endif // _LIBCPP_STD_VER >= 26
+
 #  endif // _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM &&
          // _LIBCPP_HAS_LOCALIZATION
 
diff --git a/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp b/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp
index e935a121c0ab0..a6082f700a3b3 100644
--- a/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp
+++ b/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03, c++11, c++14, c++17
+// REQUIRES: std-at-least-c++26
 
 // <chrono>
 
@@ -14,42 +14,48 @@
 
 #include <chrono>
 #include "poisoned_hash_helper.h"
-namespace chrono = std::chrono;
 
 int main(int, char**) {
-  test_hash_enabled<chrono::nanoseconds>();
-  test_hash_enabled<chrono::microseconds>();
-  test_hash_enabled<chrono::milliseconds>();
-  test_hash_enabled<chrono::seconds>();
-  test_hash_enabled<chrono::minutes>();
-  test_hash_enabled<chrono::hours>();
-  test_hash_enabled<chrono::days>();
-  test_hash_enabled<chrono::weeks>();
-  test_hash_enabled<chrono::months>();
-  test_hash_enabled<chrono::years>();
+  test_hash_enabled<std::chrono::nanoseconds>();
+  test_hash_enabled<std::chrono::microseconds>();
+  test_hash_enabled<std::chrono::milliseconds>();
+  test_hash_enabled<std::chrono::seconds>();
+  test_hash_enabled<std::chrono::minutes>();
+  test_hash_enabled<std::chrono::hours>();
+  test_hash_enabled<std::chrono::days>();
+  test_hash_enabled<std::chrono::weeks>();
+  test_hash_enabled<std::chrono::months>();
+  test_hash_enabled<std::chrono::years>();
+
+  test_hash_enabled<std::chrono::day>();
+  test_hash_enabled<std::chrono::month>();
+  test_hash_enabled<std::chrono::year>();
+
+  test_hash_enabled<std::chrono::weekday>();
+  test_hash_enabled<std::chrono::weekday_indexed>();
+  test_hash_enabled(std::chrono::weekday_last(std::chrono::weekday{}));
+
+  test_hash_enabled<std::chrono::month_day>();
+  test_hash_enabled(std::chrono::month_day_last(std::chrono::month{}));
+
+  test_hash_enabled(std::chrono::month_weekday(std::chrono::month{}, std::chrono::weekday_indexed{}));
 
-  test_hash_enabled<chrono::day>();
-  test_hash_enabled<chrono::month>();
-  test_hash_enabled<chrono::year>();
+  test_hash_enabled(
+      std::chrono::month_weekday_last(std::chrono::month{}, std::chrono::weekday_last(std::chrono::weekday{})));
 
-  test_hash_enabled<chrono::weekday>();
-  test_hash_enabled<chrono::weekday_indexed>();
-  test_hash_enabled(chrono::weekday_last(chrono::weekday{}));
+  test_hash_enabled<std::chrono::year_month>();
 
-  test_hash_enabled<chrono::month_day>();
-  test_hash_enabled(chrono::month_day_last(chrono::month{}));
+  test_hash_enabled<std::chrono::year_month_day>();
 
-  test_hash_enabled(chrono::month_weekday(chrono::month{}, chrono::weekday_indexed{}));
-  test_hash_enabled(chrono::month_weekday_last(chrono::month{}, chrono::weekday_last(chrono::weekday{})));
+  test_hash_enabled(
+      std::chrono::year_month_day_last(std::chrono::year{}, std::chrono::month_day_last(std::chrono::month{})));
 
-  test_hash_enabled<chrono::year_month>();
+  test_hash_enabled<std::chrono::year_month_weekday>();
 
-  test_hash_enabled<chrono::year_month_day>();
-  test_hash_enabled(chrono::year_month_day_last(chrono::year{}, chrono::month_day_last(chrono::month{})));
+  test_hash_enabled(std::chrono::year_month_weekday_last(
+      std::chrono::year{}, std::chrono::month{}, std::chrono::weekday_last(std::chrono::weekday{})));
 
-  test_hash_enabled<chrono::year_month_weekday>();
-  test_hash_enabled(
-      chrono::year_month_weekday_last(chrono::year{}, chrono::month{}, chrono::weekday_last(chrono::weekday{})));
+  test_hash_enabled(std::chrono::leap_second({}, std::chrono::sys_seconds{}, std::chrono::seconds{}));
 
   return 0;
 }

>From be75b5a549211fbd531475e3b679fd847bcccc4d Mon Sep 17 00:00:00 2001
From: Rafail <rafa.saddatimov at gmail.com>
Date: Sun, 26 Oct 2025 18:19:56 +0300
Subject: [PATCH 4/7] Add synopsis

---
 libcxx/include/chrono | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index 82e99a31bcc9f..c57f4d5b8e673 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -1035,6 +1035,49 @@ constexpr chrono::year                                  operator ""y(unsigned lo
 }  // chrono_literals
 }  // literals
 
+namespace std {
+  template<class T>
+    struct hash;                                            // C++26
+  template<class Rep, class Period>
+    struct hash<chrono::duration<Rep, Period>>;             // C++26
+  template<class Clock, class Duration>
+    struct hash<chrono::time_point<Clock, Duration>>;       // C++26
+  template<>
+    struct hash<chrono::day>;                               // C++26
+  template<>
+    struct hash<chrono::month>;                             // C++26
+  template<>
+    struct hash<chrono::year>;                              // C++26
+  template<>
+    struct hash<chrono::weekday>;                           // C++26
+  template<>
+    struct hash<chrono::weekday_indexed>;                   // C++26
+  template<>
+    struct hash<chrono::weekday_last>;                      // C++26
+  template<>
+    struct hash<chrono::month_day>;                         // C++26
+  template<>
+    struct hash<chrono::month_day_last>;                    // C++26
+  template<>
+    struct hash<chrono::month_weekday>;                     // C++26
+  template<>
+    struct hash<chrono::month_weekday_last>;                // C++26
+  template<>
+    struct hash<chrono::year_month>;                        // C++26
+  template<>
+    struct hash<chrono::year_month_day>;                    // C++26
+  template<>
+    struct hash<chrono::year_month_day_last>;               // C++26
+  template<>
+    struct hash<chrono::year_month_weekday>;                // C++26
+  template<>
+    struct hash<chrono::year_month_weekday_last>;           // C++26
+  template<class Duration, class TimeZonePtr>
+    struct hash<chrono::zoned_time<Duration, TimeZonePtr>>; // C++26
+  template<>
+    struct hash<chrono::leap_second>;                       // C++26
+} // namespace std
+
 }  // std
 */
 

>From dd7aaa2e1752670f0b91a0a5cf14dc96fee6e3e3 Mon Sep 17 00:00:00 2001
From: Rafail <rafa.saddatimov at gmail.com>
Date: Mon, 27 Oct 2025 08:48:07 +0300
Subject: [PATCH 5/7] Fix issues & revert version bump

---
 libcxx/docs/FeatureTestMacroTable.rst         |  2 --
 libcxx/include/__chrono/day.h                 |  4 ++--
 libcxx/include/__chrono/duration.h            |  4 ++--
 libcxx/include/__chrono/leap_second.h         |  6 +++---
 libcxx/include/__chrono/month.h               |  4 ++--
 libcxx/include/__chrono/month_weekday.h       | 14 +++++++------
 libcxx/include/__chrono/monthday.h            | 10 +++++-----
 libcxx/include/__chrono/time_point.h          |  5 ++---
 libcxx/include/__chrono/weekday.h             | 14 ++++++-------
 libcxx/include/__chrono/year.h                |  4 ++--
 libcxx/include/__chrono/year_month.h          |  6 +++---
 libcxx/include/__chrono/year_month_day.h      | 15 ++++++++------
 libcxx/include/__chrono/year_month_weekday.h  | 20 +++++++++++--------
 libcxx/include/__chrono/zoned_time.h          |  8 ++++----
 libcxx/include/version                        |  5 +----
 .../chrono.version.compile.pass.cpp           |  4 ++--
 .../version.version.compile.pass.cpp          |  4 ++--
 .../generate_feature_test_macro_components.py |  2 +-
 18 files changed, 67 insertions(+), 64 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 51c2c720cdf9a..8fba6db871f08 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -424,8 +424,6 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_bitset``                                       ``202306L``
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_chrono``                                       ``202306L``
-    ---------------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_algorithms``                         ``202306L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_forward_list``                       ``202502L``
diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h
index 2478f25214912..a8de0aa0fe50e 100644
--- a/libcxx/include/__chrono/day.h
+++ b/libcxx/include/__chrono/day.h
@@ -96,8 +96,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) no
 #  if _LIBCPP_STD_VER >= 26
 
 template <>
-struct hash<chrono::day> : public __unary_function<chrono::day, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::day& __d) const _NOEXCEPT {
+struct hash<chrono::day> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::day& __d) noexcept {
     return hash<unsigned>{}(static_cast<unsigned>(__d));
   }
 };
diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h
index c92ab4a5ffddf..24865ca9244bc 100644
--- a/libcxx/include/__chrono/duration.h
+++ b/libcxx/include/__chrono/duration.h
@@ -543,8 +543,8 @@ using namespace literals::chrono_literals;
 
 template <class _Rep, class _Period>
   requires __has_enabled_hash<_Rep>::value
-struct hash<chrono::duration<_Rep, _Period>> : public __unary_function<chrono::duration<_Rep, _Period>, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::duration<_Rep, _Period>& __d) const {
+struct hash<chrono::duration<_Rep, _Period>> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::duration<_Rep, _Period>& __d) {
     return hash<_Rep>{}(__d.count());
   }
 };
diff --git a/libcxx/include/__chrono/leap_second.h b/libcxx/include/__chrono/leap_second.h
index 8d3eafbde4639..d8d88a20fafbb 100644
--- a/libcxx/include/__chrono/leap_second.h
+++ b/libcxx/include/__chrono/leap_second.h
@@ -126,9 +126,9 @@ class leap_second {
 #    if _LIBCPP_STD_VER >= 26
 
 template <>
-struct hash<chrono::leap_second> : public __unary_function<chrono::leap_second, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::leap_second& __lp) const _NOEXCEPT {
-    return hash<chrono::seconds>{}(__lp.value());
+struct hash<chrono::leap_second> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::leap_second& __lp) noexcept {
+    return std::__hash_combine(hash<chrono::sys_seconds>{}(__lp.date()), hash<chrono::seconds>{}(__lp.value()));
   }
 };
 
diff --git a/libcxx/include/__chrono/month.h b/libcxx/include/__chrono/month.h
index 470451e8153fe..451d9222b7c9a 100644
--- a/libcxx/include/__chrono/month.h
+++ b/libcxx/include/__chrono/month.h
@@ -112,8 +112,8 @@ inline constexpr month December{12};
 #  if _LIBCPP_STD_VER >= 26
 
 template <>
-struct hash<chrono::month> : public __unary_function<chrono::month, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month& __m) const _NOEXCEPT {
+struct hash<chrono::month> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month& __m) noexcept {
     return hash<unsigned>{}(static_cast<unsigned>(__m));
   }
 };
diff --git a/libcxx/include/__chrono/month_weekday.h b/libcxx/include/__chrono/month_weekday.h
index 58ef6b8540351..dab61a4a89576 100644
--- a/libcxx/include/__chrono/month_weekday.h
+++ b/libcxx/include/__chrono/month_weekday.h
@@ -102,16 +102,18 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(const weekda
 #  if _LIBCPP_STD_VER >= 26
 
 template <>
-struct hash<chrono::month_weekday> : public __unary_function<chrono::month_weekday, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday& __mw) const _NOEXCEPT {
-    return hash<chrono::month>{}(__mw.month()) ^ hash<chrono::weekday_indexed>{}(__mw.weekday_indexed());
+struct hash<chrono::month_weekday> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_weekday& __mw) noexcept {
+    return std::__hash_combine(
+        hash<chrono::month>{}(__mw.month()), hash<chrono::weekday_indexed>{}(__mw.weekday_indexed()));
   }
 };
 
 template <>
-struct hash<chrono::month_weekday_last> : public __unary_function<chrono::month_weekday_last, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday_last& __mwl) const _NOEXCEPT {
-    return hash<chrono::month>{}(__mwl.month()) ^ hash<chrono::weekday_last>{}(__mwl.weekday_last());
+struct hash<chrono::month_weekday_last> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_weekday_last& __mwl) noexcept {
+    return std::__hash_combine(
+        hash<chrono::month>{}(__mwl.month()), hash<chrono::weekday_last>{}(__mwl.weekday_last()));
   }
 };
 
diff --git a/libcxx/include/__chrono/monthday.h b/libcxx/include/__chrono/monthday.h
index 961c131854e9b..3d58fb3c003ea 100644
--- a/libcxx/include/__chrono/monthday.h
+++ b/libcxx/include/__chrono/monthday.h
@@ -130,15 +130,15 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, int _
 #  if _LIBCPP_STD_VER >= 26
 
 template <>
-struct hash<chrono::month_day> : public __unary_function<chrono::month_day, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day& __md) const _NOEXCEPT {
-    return hash<chrono::month>{}(__md.month()) ^ hash<chrono::day>{}(__md.day());
+struct hash<chrono::month_day> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_day& __md) noexcept {
+    return std::__hash_combine(hash<chrono::month>{}(__md.month()), hash<chrono::day>{}(__md.day()));
   }
 };
 
 template <>
-struct hash<chrono::month_day_last> : public __unary_function<chrono::month_day_last, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day_last& __mdl) const _NOEXCEPT {
+struct hash<chrono::month_day_last> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_day_last& __mdl) noexcept {
     return hash<chrono::month>{}(__mdl.month());
   }
 };
diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h
index 85a91e9b35895..c5da75b5dee23 100644
--- a/libcxx/include/__chrono/time_point.h
+++ b/libcxx/include/__chrono/time_point.h
@@ -229,9 +229,8 @@ operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock,
 
 template <class _Clock, class _Duration>
   requires __has_enabled_hash<_Duration>::value
-struct hash<chrono::time_point<_Clock, _Duration>>
-    : public __unary_function<chrono::time_point<_Clock, _Duration>, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::time_point<_Clock, _Duration>& __tp) const {
+struct hash<chrono::time_point<_Clock, _Duration>> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::time_point<_Clock, _Duration>& __tp) {
     return hash<_Duration>{}(__tp.time_since_epoch());
   }
 };
diff --git a/libcxx/include/__chrono/weekday.h b/libcxx/include/__chrono/weekday.h
index 3842f44f3bf9f..e12fc0a8a95ca 100644
--- a/libcxx/include/__chrono/weekday.h
+++ b/libcxx/include/__chrono/weekday.h
@@ -164,22 +164,22 @@ inline constexpr weekday Saturday{6};
 #  if _LIBCPP_STD_VER >= 26
 
 template <>
-struct hash<chrono::weekday> : public __unary_function<chrono::weekday, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday& __w) const _NOEXCEPT {
+struct hash<chrono::weekday> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday& __w) noexcept {
     return hash<unsigned>{}(__w.c_encoding());
   }
 };
 
 template <>
-struct hash<chrono::weekday_indexed> : public __unary_function<chrono::weekday_indexed, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday_indexed& __wi) const _NOEXCEPT {
-    return hash<chrono::weekday>{}(__wi.weekday()) ^ hash<unsigned>{}(__wi.index());
+struct hash<chrono::weekday_indexed> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday_indexed& __wi) noexcept {
+    return std::__hash_combine(hash<chrono::weekday>{}(__wi.weekday()), hash<unsigned>{}(__wi.index()));
   }
 };
 
 template <>
-struct hash<chrono::weekday_last> : public __unary_function<chrono::weekday_last, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday_last& __wl) const _NOEXCEPT {
+struct hash<chrono::weekday_last> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday_last& __wl) noexcept {
     return hash<chrono::weekday>{}(__wl.weekday());
   }
 };
diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h
index e2f8985732d4d..cb7d892477dbb 100644
--- a/libcxx/include/__chrono/year.h
+++ b/libcxx/include/__chrono/year.h
@@ -113,8 +113,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept {
 #  if _LIBCPP_STD_VER >= 26
 
 template <>
-struct hash<chrono::year> : public __unary_function<chrono::year, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year& __y) const _NOEXCEPT {
+struct hash<chrono::year> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year& __y) noexcept {
     return hash<int>{}(static_cast<int>(__y));
   }
 };
diff --git a/libcxx/include/__chrono/year_month.h b/libcxx/include/__chrono/year_month.h
index 6d6b14d952982..5bc4bb390b226 100644
--- a/libcxx/include/__chrono/year_month.h
+++ b/libcxx/include/__chrono/year_month.h
@@ -120,9 +120,9 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const
 #  if _LIBCPP_STD_VER >= 26
 
 template <>
-struct hash<chrono::year_month> : public __unary_function<chrono::year_month, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month& __ym) const _NOEXCEPT {
-    return hash<chrono::year>{}(__ym.year()) ^ hash<chrono::month>{}(__ym.month());
+struct hash<chrono::year_month> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month& __ym) noexcept {
+    return std::__hash_combine(hash<chrono::year>{}(__ym.year()), hash<chrono::month>{}(__ym.month()));
   }
 };
 
diff --git a/libcxx/include/__chrono/year_month_day.h b/libcxx/include/__chrono/year_month_day.h
index c1661a1b7614b..826e8eefe96dd 100644
--- a/libcxx/include/__chrono/year_month_day.h
+++ b/libcxx/include/__chrono/year_month_day.h
@@ -334,16 +334,19 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool year_month_day::ok() const noexcept
 #  if _LIBCPP_STD_VER >= 26
 
 template <>
-struct hash<chrono::year_month_day> : public __unary_function<chrono::year_month_day, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_day& __ymd) const _NOEXCEPT {
-    return hash<chrono::year>{}(__ymd.year()) ^ hash<chrono::month>{}(__ymd.month()) ^ hash<chrono::day>{}(__ymd.day());
+struct hash<chrono::year_month_day> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_day& __ymd) noexcept {
+    return std::__hash_combine(
+        hash<chrono::year>{}(__ymd.year()),
+        std::__hash_combine(hash<chrono::month>{}(__ymd.month()), hash<chrono::day>{}(__ymd.day())));
   }
 };
 
 template <>
-struct hash<chrono::year_month_day_last> : public __unary_function<chrono::year_month_day_last, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_day_last& __ymdl) const _NOEXCEPT {
-    return hash<chrono::year>{}(__ymdl.year()) ^ hash<chrono::month_day_last>{}(__ymdl.month_day_last());
+struct hash<chrono::year_month_day_last> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_day_last& __ymdl) noexcept {
+    return std::__hash_combine(
+        hash<chrono::year>{}(__ymdl.year()), hash<chrono::month_day_last>{}(__ymdl.month_day_last()));
   }
 };
 
diff --git a/libcxx/include/__chrono/year_month_weekday.h b/libcxx/include/__chrono/year_month_weekday.h
index ae7e21747d2a4..9b4632d57c7fa 100644
--- a/libcxx/include/__chrono/year_month_weekday.h
+++ b/libcxx/include/__chrono/year_month_weekday.h
@@ -284,18 +284,22 @@ year_month_weekday_last::operator-=(const years& __dy) noexcept {
 #  if _LIBCPP_STD_VER >= 26
 
 template <>
-struct hash<chrono::year_month_weekday> : public __unary_function<chrono::year_month_weekday, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_weekday& __ymw) const _NOEXCEPT {
-    return hash<chrono::year>{}(__ymw.year()) ^ hash<chrono::month>{}(__ymw.month()) ^
-           hash<chrono::weekday_indexed>{}(__ymw.weekday_indexed());
+struct hash<chrono::year_month_weekday> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_weekday& __ymw) noexcept {
+    return std::__hash_combine(
+        hash<chrono::year>{}(__ymw.year()),
+        std::__hash_combine(
+            hash<chrono::month>{}(__ymw.month()), hash<chrono::weekday_indexed>{}(__ymw.weekday_indexed())));
   }
 };
 
 template <>
-struct hash<chrono::year_month_weekday_last> : public __unary_function<chrono::year_month_weekday_last, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_weekday_last& __ymwl) const _NOEXCEPT {
-    return hash<chrono::year>{}(__ymwl.year()) ^ hash<chrono::month>{}(__ymwl.month()) ^
-           hash<chrono::weekday_last>{}(__ymwl.weekday_last());
+struct hash<chrono::year_month_weekday_last> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_weekday_last& __ymwl) noexcept {
+    return std::__hash_combine(
+        hash<chrono::year>{}(__ymwl.year()),
+        std::__hash_combine(
+            hash<chrono::month>{}(__ymwl.month()), hash<chrono::weekday_last>{}(__ymwl.weekday_last())));
   }
 };
 
diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h
index 595d0ce4d3d1c..2c763bce3bd95 100644
--- a/libcxx/include/__chrono/zoned_time.h
+++ b/libcxx/include/__chrono/zoned_time.h
@@ -221,10 +221,10 @@ operator==(const zoned_time<_Duration1, _TimeZonePtr>& __lhs, const zoned_time<_
 
 template <class _Duration, class _TimeZonePtr>
   requires __has_enabled_hash<_Duration>::value && __has_enabled_hash<_TimeZonePtr>::value
-struct hash<chrono::zoned_time<_Duration, _TimeZonePtr>>
-    : public __unary_function<chrono::zoned_time<_Duration, _TimeZonePtr>, size_t> {
-  _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::zoned_time<_Duration, _TimeZonePtr>& __zt) const {
-    return hash<chrono::sys_time<_Duration>>{}(__zt.get_sys_time()) ^ hash<_TimeZonePtr>{}(__zt.get_time_zone());
+struct hash<chrono::zoned_time<_Duration, _TimeZonePtr>> {
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::zoned_time<_Duration, _TimeZonePtr>& __zt) {
+    return std::__hash_combine(
+        hash<chrono::sys_time<_Duration>>{}(__zt.get_sys_time()), hash<_TimeZonePtr>{}(__zt.get_time_zone()));
   }
 };
 
diff --git a/libcxx/include/version b/libcxx/include/version
index 07cc828bd7c53..0fef1bb87cf60 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -57,8 +57,7 @@ __cpp_lib_byteswap                                      202110L <bit>
 __cpp_lib_char8_t                                       201907L <atomic> <filesystem> <istream>
                                                                 <limits> <locale> <ostream>
                                                                 <string> <string_view>
-__cpp_lib_chrono                                        202306L <chrono>
-                                                        201611L // C++17
+__cpp_lib_chrono                                        201611L <chrono>
 __cpp_lib_chrono_udls                                   201304L <chrono>
 __cpp_lib_clamp                                         201603L <algorithm>
 __cpp_lib_common_reference                              202302L <type_traits>
@@ -551,8 +550,6 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # undef  __cpp_lib_bind_front
 # define __cpp_lib_bind_front                           202306L
 # define __cpp_lib_bitset                               202306L
-# undef  __cpp_lib_chrono
-# define __cpp_lib_chrono                               202306L
 # undef  __cpp_lib_constexpr_algorithms
 # define __cpp_lib_constexpr_algorithms                 202306L
 # define __cpp_lib_constexpr_forward_list               202502L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp
index 98b3eda149342..d5d7a5da4a64d 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp
@@ -94,8 +94,8 @@
 #  ifndef __cpp_lib_chrono
 #    error "__cpp_lib_chrono should be defined in c++26"
 #  endif
-#  if __cpp_lib_chrono != 202306L
-#    error "__cpp_lib_chrono should have the value 202306L in c++26"
+#  if __cpp_lib_chrono != 201611L
+#    error "__cpp_lib_chrono should have the value 201611L in c++26"
 #  endif
 
 #  ifndef __cpp_lib_chrono_udls
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 1ecba19d39abe..05af1fb0cf14b 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -6455,8 +6455,8 @@
 #  ifndef __cpp_lib_chrono
 #    error "__cpp_lib_chrono should be defined in c++26"
 #  endif
-#  if __cpp_lib_chrono != 202306L
-#    error "__cpp_lib_chrono should have the value 202306L in c++26"
+#  if __cpp_lib_chrono != 201611L
+#    error "__cpp_lib_chrono should have the value 201611L in c++26"
 #  endif
 
 #  ifndef __cpp_lib_chrono_udls
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 114f844cc238e..f6f252751b3e3 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -300,7 +300,7 @@ def add_version_header(tc):
             "name": "__cpp_lib_chrono",
             "values": {
                 "c++17": 201611,
-                "c++26": 202306, # P2592R3 Hashing support for std::chrono value classes
+                # "c++26": 202306, # P2592R3 Hashing support for std::chrono value classes
             },
             "headers": ["chrono"],
         },

>From 5939a5ee82d40e2d188e719b64bbac429d4b468e Mon Sep 17 00:00:00 2001
From: Rafail <rafa.saddatimov at gmail.com>
Date: Mon, 27 Oct 2025 18:59:31 +0300
Subject: [PATCH 6/7] Fix size_t include issues

---
 libcxx/include/__chrono/day.h                    | 1 +
 libcxx/include/__chrono/duration.h               | 1 +
 libcxx/include/__chrono/leap_second.h            | 1 +
 libcxx/include/__chrono/month.h                  | 1 +
 libcxx/include/__chrono/month_weekday.h          | 1 +
 libcxx/include/__chrono/monthday.h               | 1 +
 libcxx/include/__chrono/time_point.h             | 1 +
 libcxx/include/__chrono/weekday.h                | 1 +
 libcxx/include/__chrono/year.h                   | 1 +
 libcxx/include/__chrono/year_month.h             | 1 +
 libcxx/include/__chrono/year_month_day.h         | 1 +
 libcxx/include/__chrono/year_month_weekday.h     | 1 +
 libcxx/include/__chrono/zoned_time.h             | 1 +
 libcxx/test/libcxx/transitive_includes/cxx26.csv | 3 +++
 14 files changed, 16 insertions(+)

diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h
index a8de0aa0fe50e..88a5ee5b837fa 100644
--- a/libcxx/include/__chrono/day.h
+++ b/libcxx/include/__chrono/day.h
@@ -13,6 +13,7 @@
 #include <__chrono/duration.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h
index 24865ca9244bc..01432bd3fa259 100644
--- a/libcxx/include/__chrono/duration.h
+++ b/libcxx/include/__chrono/duration.h
@@ -13,6 +13,7 @@
 #include <__compare/ordering.h>
 #include <__compare/three_way_comparable.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__functional/hash.h>
 #include <__type_traits/common_type.h>
 #include <__type_traits/enable_if.h>
diff --git a/libcxx/include/__chrono/leap_second.h b/libcxx/include/__chrono/leap_second.h
index d8d88a20fafbb..665056e5a963e 100644
--- a/libcxx/include/__chrono/leap_second.h
+++ b/libcxx/include/__chrono/leap_second.h
@@ -22,6 +22,7 @@
 #  include <__compare/ordering.h>
 #  include <__compare/three_way_comparable.h>
 #  include <__config>
+#  include <__cstddef/size_t.h>
 #  include <__functional/hash.h>
 #  include <__utility/private_constructor_tag.h>
 
diff --git a/libcxx/include/__chrono/month.h b/libcxx/include/__chrono/month.h
index 451d9222b7c9a..b9ba29b0e8b6b 100644
--- a/libcxx/include/__chrono/month.h
+++ b/libcxx/include/__chrono/month.h
@@ -13,6 +13,7 @@
 #include <__chrono/duration.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/__chrono/month_weekday.h b/libcxx/include/__chrono/month_weekday.h
index dab61a4a89576..edb7d386067d8 100644
--- a/libcxx/include/__chrono/month_weekday.h
+++ b/libcxx/include/__chrono/month_weekday.h
@@ -13,6 +13,7 @@
 #include <__chrono/month.h>
 #include <__chrono/weekday.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/__chrono/monthday.h b/libcxx/include/__chrono/monthday.h
index 3d58fb3c003ea..2a7262be09dc6 100644
--- a/libcxx/include/__chrono/monthday.h
+++ b/libcxx/include/__chrono/monthday.h
@@ -15,6 +15,7 @@
 #include <__chrono/month.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h
index c5da75b5dee23..438f065c1d99d 100644
--- a/libcxx/include/__chrono/time_point.h
+++ b/libcxx/include/__chrono/time_point.h
@@ -14,6 +14,7 @@
 #include <__compare/ordering.h>
 #include <__compare/three_way_comparable.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__functional/hash.h>
 #include <__type_traits/common_type.h>
 #include <__type_traits/enable_if.h>
diff --git a/libcxx/include/__chrono/weekday.h b/libcxx/include/__chrono/weekday.h
index e12fc0a8a95ca..f56274c82bc68 100644
--- a/libcxx/include/__chrono/weekday.h
+++ b/libcxx/include/__chrono/weekday.h
@@ -15,6 +15,7 @@
 #include <__chrono/system_clock.h>
 #include <__chrono/time_point.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h
index cb7d892477dbb..9223f3cb926ea 100644
--- a/libcxx/include/__chrono/year.h
+++ b/libcxx/include/__chrono/year.h
@@ -13,6 +13,7 @@
 #include <__chrono/duration.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__functional/hash.h>
 #include <limits>
 
diff --git a/libcxx/include/__chrono/year_month.h b/libcxx/include/__chrono/year_month.h
index 5bc4bb390b226..e36091c02161b 100644
--- a/libcxx/include/__chrono/year_month.h
+++ b/libcxx/include/__chrono/year_month.h
@@ -15,6 +15,7 @@
 #include <__chrono/year.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/__chrono/year_month_day.h b/libcxx/include/__chrono/year_month_day.h
index 826e8eefe96dd..0a2aaedd60505 100644
--- a/libcxx/include/__chrono/year_month_day.h
+++ b/libcxx/include/__chrono/year_month_day.h
@@ -21,6 +21,7 @@
 #include <__chrono/year_month.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__functional/hash.h>
 #include <limits>
 
diff --git a/libcxx/include/__chrono/year_month_weekday.h b/libcxx/include/__chrono/year_month_weekday.h
index 9b4632d57c7fa..6ed1e21fe97e5 100644
--- a/libcxx/include/__chrono/year_month_weekday.h
+++ b/libcxx/include/__chrono/year_month_weekday.h
@@ -22,6 +22,7 @@
 #include <__chrono/year_month.h>
 #include <__chrono/year_month_day.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__functional/hash.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h
index 2c763bce3bd95..b8d33bb7f3ac7 100644
--- a/libcxx/include/__chrono/zoned_time.h
+++ b/libcxx/include/__chrono/zoned_time.h
@@ -24,6 +24,7 @@
 #  include <__chrono/tzdb_list.h>
 #  include <__concepts/constructible.h>
 #  include <__config>
+#  include <__cstddef/size_t.h>
 #  include <__functional/hash.h>
 #  include <__type_traits/common_type.h>
 #  include <__type_traits/conditional.h>
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index d047b29b63cc6..872bd5e0fe740 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -654,6 +654,7 @@ memory_resource cerrno
 memory_resource climits
 memory_resource compare
 memory_resource cstdint
+memory_resource cstring
 memory_resource ctime
 memory_resource limits
 memory_resource ratio
@@ -663,6 +664,7 @@ mutex cerrno
 mutex climits
 mutex compare
 mutex cstdint
+mutex cstring
 mutex ctime
 mutex limits
 mutex ratio
@@ -859,6 +861,7 @@ set version
 shared_mutex cerrno
 shared_mutex climits
 shared_mutex cstdint
+shared_mutex cstring
 shared_mutex ctime
 shared_mutex limits
 shared_mutex ratio

>From 152b3dc3f317ed1ff1bec3fc3b29289dac3d9d2b Mon Sep 17 00:00:00 2001
From: Rafail <rafa.saddatimov at gmail.com>
Date: Mon, 27 Oct 2025 19:02:08 +0300
Subject: [PATCH 7/7] Identity for hash<day>

---
 libcxx/include/__chrono/day.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h
index 88a5ee5b837fa..46822c599192d 100644
--- a/libcxx/include/__chrono/day.h
+++ b/libcxx/include/__chrono/day.h
@@ -98,9 +98,7 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) no
 
 template <>
 struct hash<chrono::day> {
-  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::day& __d) noexcept {
-    return hash<unsigned>{}(static_cast<unsigned>(__d));
-  }
+  _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::day& __d) noexcept { return static_cast<unsigned>(__d); }
 };
 
 #  endif // _LIBCPP_STD_VER >= 26



More information about the libcxx-commits mailing list