[libcxx-commits] [libcxx] 105fef5 - [libc++][chrono] Add calendar type formatters.

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Sat Dec 24 06:11:49 PST 2022


Author: Mark de Wever
Date: 2022-12-24T15:11:41+01:00
New Revision: 105fef5dca7ea224bf44a13ff3685fb1f3ae0876

URL: https://github.com/llvm/llvm-project/commit/105fef5dca7ea224bf44a13ff3685fb1f3ae0876
DIFF: https://github.com/llvm/llvm-project/commit/105fef5dca7ea224bf44a13ff3685fb1f3ae0876.diff

LOG: [libc++][chrono] Add calendar type formatters.

Some of the calendar types have landed before, this adds the missing
set. Note this does not complete the implementation of the chrono
formatters.

This removes the `chrono` header for some transitive include in C++17
mode. This is needed to avoid inclusion cycles.

Partially implements:
- P1361 Integration of chrono with text formatting
- P2372 Fixing locale handling in chrono formatters

Reviewed By: #libc, ldionne

Differential Revision: https://reviews.llvm.org/D137022

Added: 
    libcxx/test/std/time/time.cal/time.cal.md/time.cal.md.nonmembers/ostream.pass.cpp
    libcxx/test/std/time/time.cal/time.cal.mdlast/ostream.pass.cpp
    libcxx/test/std/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/ostream.pass.cpp
    libcxx/test/std/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/ostream.pass.cpp
    libcxx/test/std/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/ostream.pass.cpp
    libcxx/test/std/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/ostream.pass.cpp
    libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/ostream.pass.cpp
    libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/ostream.pass.cpp
    libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/ostream.pass.cpp
    libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/ostream.pass.cpp
    libcxx/test/std/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/ostream.pass.cpp
    libcxx/test/std/time/time.syn/formatter.month_day.pass.cpp
    libcxx/test/std/time/time.syn/formatter.month_day_last.pass.cpp
    libcxx/test/std/time/time.syn/formatter.month_weekday.pass.cpp
    libcxx/test/std/time/time.syn/formatter.weekday_index.pass.cpp
    libcxx/test/std/time/time.syn/formatter.weekday_last.pass.cpp
    libcxx/test/std/time/time.syn/formatter.year_month.pass.cpp
    libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp
    libcxx/test/std/time/time.syn/formatter.year_month_day_last.pass.cpp
    libcxx/test/std/time/time.syn/formatter.year_month_weekday.pass.cpp
    libcxx/test/std/time/time.syn/formatter.year_month_weekday_last.pass.cpp

Modified: 
    libcxx/docs/ReleaseNotes.rst
    libcxx/docs/Status/FormatPaper.csv
    libcxx/include/__chrono/convert_to_tm.h
    libcxx/include/__chrono/formatter.h
    libcxx/include/__chrono/ostream.h
    libcxx/include/__chrono/parser_std_format_spec.h
    libcxx/include/__format/parser_std_format_spec.h
    libcxx/include/atomic
    libcxx/include/chrono
    libcxx/include/optional
    libcxx/test/libcxx/transitive_includes/cxx03.csv
    libcxx/test/libcxx/transitive_includes/cxx11.csv
    libcxx/test/libcxx/transitive_includes/cxx14.csv
    libcxx/test/libcxx/transitive_includes/cxx17.csv
    libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 3929be5c459ad..ba710c04e1af8 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -67,6 +67,7 @@ Deprecations and Removals
   includes are removed based on the language version used. Incidental transitive
   inclusions of the following headers have been removed:
 
+  - C++11, C++14, and C++17: ``chrono``
   - C++20: ``chrono``
   - C++2b: ``algorithm``, ``array``, ``atomic``, ``bit``, ``chrono``,
     ``climits``, ``cmath``, ``compare``, ``concepts``, ``cstdarg``, ``cstddef``,

diff  --git a/libcxx/docs/Status/FormatPaper.csv b/libcxx/docs/Status/FormatPaper.csv
index 718c1d5329ccb..4a5f1c4b1e2dd 100644
--- a/libcxx/docs/Status/FormatPaper.csv
+++ b/libcxx/docs/Status/FormatPaper.csv
@@ -11,18 +11,18 @@ Section,Description,Dependencies,Assignee,Status,First released version
 `[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::day``",,Mark de Wever,|Complete|, Clang 16
 `[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::month``",,Mark de Wever,|Complete|, Clang 16
 `[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year``",,Mark de Wever,|Complete|, Clang 16
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::weekday``",,Mark de Wever,|In Progress|,
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::weekday_indexed``",,Mark de Wever,|In Progress|,
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::weekday_last``",,Mark de Wever,|In Progress|,
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::month_day``",,Mark de Wever,|In Progress|,
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::month_day_last``",,Mark de Wever,|In Progress|,
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::month_weekday``",,Mark de Wever,|In Progress|,
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::month_weekday_last``",,Mark de Wever,|In Progress|,
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month``",,Mark de Wever,|In Progress|,
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month_day``",,Mark de Wever,|In Progress|,
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month_day_last``",,Mark de Wever,|In Progress|,
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month_weekday``",,Mark de Wever,|In Progress|,
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month_weekday_last``",,Mark de Wever,|In Progress|,
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::weekday``",,Mark de Wever,|Complete|, Clang 16
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::weekday_indexed``",,Mark de Wever,|Complete|, Clang 16
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::weekday_last``",,Mark de Wever,|Complete|, Clang 16
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::month_day``",,Mark de Wever,|Complete|, Clang 16
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::month_day_last``",,Mark de Wever,|Complete|, Clang 16
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::month_weekday``",,Mark de Wever,|Complete|, Clang 16
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::month_weekday_last``",,Mark de Wever,|Complete|, Clang 16
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month``",,Mark de Wever,|Complete|, Clang 16
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month_day``",,Mark de Wever,|Complete|, Clang 16
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month_day_last``",,Mark de Wever,|Complete|, Clang 16
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month_weekday``",,Mark de Wever,|Complete|, Clang 16
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month_weekday_last``",,Mark de Wever,|Complete|, Clang 16
 `[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::hh_mm_ss<duration<Rep, Period>>``",,Mark de Wever,|In Progress|,
 `[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::sys_info``",A ``<chrono>`` implementation,Mark de Wever,,
 `[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::local_info``",A ``<chrono>`` implementation,Mark de Wever,,

diff  --git a/libcxx/include/__chrono/convert_to_tm.h b/libcxx/include/__chrono/convert_to_tm.h
index dea9758efb8ae..0974e9466601b 100644
--- a/libcxx/include/__chrono/convert_to_tm.h
+++ b/libcxx/include/__chrono/convert_to_tm.h
@@ -12,12 +12,23 @@
 
 #include <__chrono/day.h>
 #include <__chrono/duration.h>
+#include <__chrono/hh_mm_ss.h>
 #include <__chrono/month.h>
+#include <__chrono/month_weekday.h>
+#include <__chrono/monthday.h>
+#include <__chrono/statically_widen.h>
+#include <__chrono/system_clock.h>
+#include <__chrono/time_point.h>
 #include <__chrono/weekday.h>
 #include <__chrono/year.h>
+#include <__chrono/year_month.h>
+#include <__chrono/year_month_day.h>
+#include <__chrono/year_month_weekday.h>
 #include <__concepts/same_as.h>
 #include <__config>
+#include <__memory/addressof.h>
 #include <cstdint>
+#include <ctime>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -27,6 +38,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if _LIBCPP_STD_VER > 17
 
+// Conerts a chrono date and weekday to a given _Tm type.
+//
+// This is an implementation detail for the function
+//   template <class _Tm, class _ChronoT>
+//   _Tm __convert_to_tm(const _ChronoT& __value)
+//
+// This manually converts the two values to the proper type. It is possible to
+// convert from sys_days to time_t and then to _Tm. But this leads to the Y2K
+// bug when time_t is a 32-bit signed integer. Chrono considers years beyond
+// the year 2038 valid, so instead do the transformation manually.
+template <class _Tm, class _Date>
+  requires(same_as<_Date, chrono::year_month_day> || same_as<_Date, chrono::year_month_day_last>)
+_LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _Date& __date, chrono::weekday __weekday) {
+  _Tm __result = {};
+#  ifdef __GLIBC__
+  __result.tm_zone = "UTC";
+#  endif
+  __result.tm_year = static_cast<int>(__date.year()) - 1900;
+  __result.tm_mon  = static_cast<unsigned>(__date.month()) - 1;
+  __result.tm_mday = static_cast<unsigned>(__date.day());
+  __result.tm_wday = static_cast<unsigned>(__weekday.c_encoding());
+  __result.tm_yday =
+      (static_cast<chrono::sys_days>(__date) -
+       static_cast<chrono::sys_days>(chrono::year_month_day{__date.year(), chrono::January, chrono::day{1}}))
+          .count();
+
+  return __result;
+}
+
 // Convert a chrono (calendar) time point, or dururation to the given _Tm type,
 // which must have the same properties as std::tm.
 template <class _Tm, class _ChronoT>
@@ -55,7 +95,26 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) {
     __result.tm_year = static_cast<int>(__value) - 1900;
   else if constexpr (same_as<_ChronoT, chrono::weekday>)
     __result.tm_wday = __value.c_encoding();
-  else
+  else if constexpr (same_as<_ChronoT, chrono::weekday_indexed> || same_as<_ChronoT, chrono::weekday_last>)
+    __result.tm_wday = __value.weekday().c_encoding();
+  else if constexpr (same_as<_ChronoT, chrono::month_day>) {
+    __result.tm_mday = static_cast<unsigned>(__value.day());
+    __result.tm_mon  = static_cast<unsigned>(__value.month()) - 1;
+  } else if constexpr (same_as<_ChronoT, chrono::month_day_last>) {
+    __result.tm_mon = static_cast<unsigned>(__value.month()) - 1;
+  } else if constexpr (same_as<_ChronoT, chrono::month_weekday> || same_as<_ChronoT, chrono::month_weekday_last>) {
+    __result.tm_wday = __value.weekday_indexed().weekday().c_encoding();
+    __result.tm_mon  = static_cast<unsigned>(__value.month()) - 1;
+  } else if constexpr (same_as<_ChronoT, chrono::year_month>) {
+    __result.tm_year = static_cast<int>(__value.year()) - 1900;
+    __result.tm_mon  = static_cast<unsigned>(__value.month()) - 1;
+  } else if constexpr (same_as<_ChronoT, chrono::year_month_day> || same_as<_ChronoT, chrono::year_month_day_last>) {
+    return __convert_to_tm<_Tm>(
+        chrono::year_month_day{__value}, chrono::weekday{static_cast<chrono::sys_days>(__value)});
+  } else if constexpr (same_as<_ChronoT, chrono::year_month_weekday> ||
+                       same_as<_ChronoT, chrono::year_month_weekday_last>) {
+    return __convert_to_tm<_Tm>(chrono::year_month_day{static_cast<chrono::sys_days>(__value)}, __value.weekday());
+  } else
     static_assert(sizeof(_ChronoT) == 0, "Add the missing type specialization");
 
   return __result;

diff  --git a/libcxx/include/__chrono/formatter.h b/libcxx/include/__chrono/formatter.h
index de27811f2717f..2015783acbbbe 100644
--- a/libcxx/include/__chrono/formatter.h
+++ b/libcxx/include/__chrono/formatter.h
@@ -10,17 +10,23 @@
 #ifndef _LIBCPP___CHRONO_FORMATTER_H
 #define _LIBCPP___CHRONO_FORMATTER_H
 
+#include <__chrono/calendar.h>
 #include <__chrono/convert_to_tm.h>
 #include <__chrono/day.h>
 #include <__chrono/duration.h>
 #include <__chrono/hh_mm_ss.h>
 #include <__chrono/month.h>
+#include <__chrono/month_weekday.h>
+#include <__chrono/monthday.h>
 #include <__chrono/ostream.h>
 #include <__chrono/parser_std_format_spec.h>
 #include <__chrono/statically_widen.h>
 #include <__chrono/time_point.h>
 #include <__chrono/weekday.h>
 #include <__chrono/year.h>
+#include <__chrono/year_month.h>
+#include <__chrono/year_month_day.h>
+#include <__chrono/year_month_weekday.h>
 #include <__concepts/arithmetic.h>
 #include <__concepts/same_as.h>
 #include <__config>
@@ -249,6 +255,15 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
           __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
       } break;
 
+      case _CharT('F'): {
+        int __year = __t.tm_year + 1900;
+        if (__year < 1000) {
+          __formatter::__format_year(__year, __sstr);
+          __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday);
+        } else
+          __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1);
+      } break;
+
       case _CharT('O'):
         if constexpr (__use_fraction<_Tp>()) {
           // Handle OS using the normal representation for the non-fractional
@@ -276,7 +291,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs(
 }
 
 template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
+_LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) {
   if constexpr (same_as<_Tp, chrono::day>)
     return true;
   else if constexpr (same_as<_Tp, chrono::month>)
@@ -285,6 +300,28 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
     return true;
   else if constexpr (same_as<_Tp, chrono::weekday>)
     return true;
+  else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::weekday_last>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month_day>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month_day_last>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month_weekday>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::year_month>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::year_month_day>)
+    return __value.ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
+    return __value.ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
+    return __value.weekday().ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
+    return __value.weekday().ok();
   else
     static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
 }
@@ -299,6 +336,100 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) {
     return true;
   else if constexpr (same_as<_Tp, chrono::weekday>)
     return __value.ok();
+  else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
+    return __value.weekday().ok();
+  else if constexpr (same_as<_Tp, chrono::weekday_last>)
+    return __value.weekday().ok();
+  else if constexpr (same_as<_Tp, chrono::month_day>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month_day_last>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month_weekday>)
+    return __value.weekday_indexed().ok();
+  else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
+    return __value.weekday_indexed().ok();
+  else if constexpr (same_as<_Tp, chrono::year_month>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::year_month_day>)
+    return __value.ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
+    return __value.ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
+    return __value.weekday().ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
+    return __value.weekday().ok();
+  else
+    static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) {
+  if constexpr (same_as<_Tp, chrono::day>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month>)
+    return __value.ok();
+  else if constexpr (same_as<_Tp, chrono::year>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::weekday>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::weekday_last>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month_day>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month_day_last>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month_weekday>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::year_month>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::year_month_day>)
+    return __value.ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
+    return __value.ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
+    return __value.ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
+    return __value.ok();
+  else
+    static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
+  if constexpr (same_as<_Tp, chrono::day>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month>)
+    return __value.ok();
+  else if constexpr (same_as<_Tp, chrono::year>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::weekday>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::weekday_indexed>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::weekday_last>)
+    return true;
+  else if constexpr (same_as<_Tp, chrono::month_day>)
+    return __value.month().ok();
+  else if constexpr (same_as<_Tp, chrono::month_day_last>)
+    return __value.month().ok();
+  else if constexpr (same_as<_Tp, chrono::month_weekday>)
+    return __value.month().ok();
+  else if constexpr (same_as<_Tp, chrono::month_weekday_last>)
+    return __value.month().ok();
+  else if constexpr (same_as<_Tp, chrono::year_month>)
+    return __value.month().ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_day>)
+    return __value.month().ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_day_last>)
+    return __value.month().ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_weekday>)
+    return __value.month().ok();
+  else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>)
+    return __value.month().ok();
   else
     static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
 }
@@ -331,9 +462,19 @@ __format_chrono(const _Tp& __value,
       // Note that the behaviour what the precision does isn't specified.
       __specs.__precision_ = -1;
     } else {
+      // Test __weekday_name_ before __weekday_ to give a better error.
       if (__specs.__chrono_.__weekday_name_ && !__formatter::__weekday_name_ok(__value))
         std::__throw_format_error("formatting a weekday name needs a valid weekday");
 
+      if (__specs.__chrono_.__weekday_ && !__formatter::__weekday_ok(__value))
+        std::__throw_format_error("formatting a weekday needs a valid weekday");
+
+      if (__specs.__chrono_.__day_of_year_ && !__formatter::__date_ok(__value))
+        std::__throw_format_error("formatting a day of year needs a valid date");
+
+      if (__specs.__chrono_.__week_of_year_ && !__formatter::__date_ok(__value))
+        std::__throw_format_error("formatting a week of year needs a valid date");
+
       if (__specs.__chrono_.__month_name_ && !__formatter::__month_name_ok(__value))
         std::__throw_format_error("formatting a month name from an invalid month number");
 
@@ -436,6 +577,138 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekda
   }
 };
 
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday_indexed, _CharT>
+    : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+      -> decltype(__parse_ctx.begin()) {
+    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
+  }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday_last, _CharT>
+    : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+      -> decltype(__parse_ctx.begin()) {
+    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday);
+  }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_day, _CharT>
+    : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+      -> decltype(__parse_ctx.begin()) {
+    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_day);
+  }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_day_last, _CharT>
+    : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+      -> decltype(__parse_ctx.begin()) {
+    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month);
+  }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_weekday, _CharT>
+    : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+      -> decltype(__parse_ctx.begin()) {
+    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
+  }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_weekday_last, _CharT>
+    : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+      -> decltype(__parse_ctx.begin()) {
+    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday);
+  }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month, _CharT>
+    : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+      -> decltype(__parse_ctx.begin()) {
+    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year_month);
+  }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_day, _CharT>
+    : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+      -> decltype(__parse_ctx.begin()) {
+    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+  }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_day_last, _CharT>
+    : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+      -> decltype(__parse_ctx.begin()) {
+    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+  }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_weekday, _CharT>
+    : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+      -> decltype(__parse_ctx.begin()) {
+    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+  }
+};
+
+template <__fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_weekday_last, _CharT>
+    : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx)
+      -> decltype(__parse_ctx.begin()) {
+    return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date);
+  }
+};
+
 #endif // if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
 
 _LIBCPP_END_NAMESPACE_STD

diff  --git a/libcxx/include/__chrono/ostream.h b/libcxx/include/__chrono/ostream.h
index c48bd6a8b307d..30a04bd2658b0 100644
--- a/libcxx/include/__chrono/ostream.h
+++ b/libcxx/include/__chrono/ostream.h
@@ -13,9 +13,14 @@
 #include <__chrono/day.h>
 #include <__chrono/duration.h>
 #include <__chrono/month.h>
+#include <__chrono/month_weekday.h>
+#include <__chrono/monthday.h>
 #include <__chrono/statically_widen.h>
 #include <__chrono/weekday.h>
 #include <__chrono/year.h>
+#include <__chrono/year_month.h>
+#include <__chrono/year_month_day.h>
+#include <__chrono/year_month_weekday.h>
 #include <__concepts/same_as.h>
 #include <__config>
 #include <__format/format_functions.h>
@@ -136,6 +141,94 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) {
                                           static_cast<unsigned>(__wd.c_encoding())));
 }
 
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) {
+  auto __i = __wdi.index();
+  return __os << (__i >= 1 && __i <= 5
+                      ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{}]"), __wdi.weekday(), __i)
+                      : std::format(__os.getloc(),
+                                    _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{} is not a valid index]"),
+                                    __wdi.weekday(),
+                                    __i));
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_last& __wdl) {
+  return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[last]"), __wdl.weekday());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) {
+  // TODO FMT The Standard allows 30th of February to be printed.
+  // It would be nice to show an error message instead.
+  return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{}"), __md.month(), __md.day());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day_last& __mdl) {
+  return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/last"), __mdl.month());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday& __mwd) {
+  return __os << std::format(
+             __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwd.month(), __mwd.weekday_indexed());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday_last& __mwdl) {
+  return __os << std::format(
+             __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwdl.month(), __mwdl.weekday_last());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) {
+  return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ym.year(), __ym.month());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day& __ymd) {
+  return __os << (__ymd.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F}"), __ymd)
+                             : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), __ymd));
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day_last& __ymdl) {
+  return __os << std::format(
+             __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ymdl.year(), __ymdl.month_day_last());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymwd) {
+  return __os << std::format(
+             __os.getloc(),
+             _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),
+             __ymwd.year(),
+             __ymwd.month(),
+             __ymwd.weekday_indexed());
+}
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& __ymwdl) {
+  return __os << std::format(
+             __os.getloc(),
+             _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),
+             __ymwdl.year(),
+             __ymwdl.month(),
+             __ymwdl.weekday_last());
+}
+
 } // namespace chrono
 
 #endif //if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)

diff  --git a/libcxx/include/__chrono/parser_std_format_spec.h b/libcxx/include/__chrono/parser_std_format_spec.h
index cdf7b9b15fd80..dbcfe6da608a8 100644
--- a/libcxx/include/__chrono/parser_std_format_spec.h
+++ b/libcxx/include/__chrono/parser_std_format_spec.h
@@ -243,17 +243,20 @@ class _LIBCPP_TEMPLATE_VIS __parser_chrono {
       break;
 
     case _CharT('j'):
+      __parser_.__day_of_year_ = true;
       __format_spec::__validate_date_or_duration(__flags);
       break;
 
     case _CharT('g'):
-    case _CharT('x'):
-    case _CharT('D'):
-    case _CharT('F'):
     case _CharT('G'):
     case _CharT('U'):
     case _CharT('V'):
     case _CharT('W'):
+      __parser_.__week_of_year_ = true;
+      [[fallthrough]];
+    case _CharT('x'):
+    case _CharT('D'):
+    case _CharT('F'):
       __format_spec::__validate_date(__flags);
       break;
 
@@ -267,6 +270,8 @@ class _LIBCPP_TEMPLATE_VIS __parser_chrono {
       [[fallthrough]];
     case _CharT('u'):
     case _CharT('w'):
+      __parser_.__weekday_ = true;
+      __validate_weekday(__flags);
       __format_spec::__validate_weekday(__flags);
       break;
 
@@ -373,11 +378,13 @@ class _LIBCPP_TEMPLATE_VIS __parser_chrono {
     case _CharT('U'):
     case _CharT('V'):
     case _CharT('W'):
+      __parser_.__week_of_year_ = true;
       __format_spec::__validate_date(__flags);
       break;
 
     case _CharT('u'):
     case _CharT('w'):
+      __parser_.__weekday_ = true;
       __format_spec::__validate_weekday(__flags);
       break;
 

diff  --git a/libcxx/include/__format/parser_std_format_spec.h b/libcxx/include/__format/parser_std_format_spec.h
index 69623c6fe8c61..a1c182a985913 100644
--- a/libcxx/include/__format/parser_std_format_spec.h
+++ b/libcxx/include/__format/parser_std_format_spec.h
@@ -195,6 +195,9 @@ struct __chrono {
   __alignment __alignment_ : 3;
   bool __locale_specific_form_ : 1;
   bool __weekday_name_ : 1;
+  bool __weekday_              : 1;
+  bool __day_of_year_          : 1;
+  bool __week_of_year_         : 1;
   bool __month_name_ : 1;
 };
 
@@ -318,10 +321,14 @@ class _LIBCPP_TEMPLATE_VIS __parser {
 
   _LIBCPP_HIDE_FROM_ABI __parsed_specifications<_CharT> __get_parsed_chrono_specifications(auto& __ctx) const {
     return __parsed_specifications<_CharT>{
-        .__chrono_ = __chrono{.__alignment_            = __alignment_,
-                              .__locale_specific_form_ = __locale_specific_form_,
-                              .__weekday_name_         = __weekday_name_,
-                              .__month_name_           = __month_name_},
+        .__chrono_ =
+            __chrono{.__alignment_            = __alignment_,
+                     .__locale_specific_form_ = __locale_specific_form_,
+                     .__weekday_name_         = __weekday_name_,
+                     .__weekday_              = __weekday_,
+                     .__day_of_year_          = __day_of_year_,
+                     .__week_of_year_         = __week_of_year_,
+                     .__month_name_           = __month_name_},
         .__width_{__get_width(__ctx)},
         .__precision_{__get_precision(__ctx)},
         .__fill_{__fill_}};
@@ -334,12 +341,17 @@ class _LIBCPP_TEMPLATE_VIS __parser {
   bool __reserved_0_ : 1 {false};
   __type __type_{__type::__default};
 
-  // These two flags are used for formatting chrono. Since the struct has
+  // These flags are only used for formatting chrono. Since the struct has
   // padding space left it's added to this structure.
   bool __weekday_name_ : 1 {false};
+  bool __weekday_      : 1 {false};
+
+  bool __day_of_year_  : 1 {false};
+  bool __week_of_year_ : 1 {false};
+
   bool __month_name_ : 1 {false};
 
-  uint8_t __reserved_1_ : 6 {0};
+  uint8_t __reserved_1_ : 3 {0};
   uint8_t __reserved_2_ : 6 {0};
   // These two flags are only used internally and not part of the
   // __parsed_specifications. Therefore put them at the end.

diff  --git a/libcxx/include/atomic b/libcxx/include/atomic
index 4fc565c7234b6..8914f19c6acad 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -2655,10 +2655,6 @@ typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
 
 _LIBCPP_END_NAMESPACE_STD
 
-#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
-#  include <chrono>
-#endif
-
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <cmath>
 #  include <compare>

diff  --git a/libcxx/include/chrono b/libcxx/include/chrono
index 05e4b6d126ebf..44073b557ba12 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -385,18 +385,29 @@ class weekday_indexed;
 constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept;
 constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept;
 
+template<class charT, class traits>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const weekday_indexed& wdi);
+
 // 25.8.8, class weekday_last    // C++20
 class weekday_last;
 
 constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept;
 constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept;
 
+template<class charT, class traits>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const weekday_last& wdl);
+
 // 25.8.9, class month_day    // C++20
 class month_day;
 
 constexpr bool operator==(const month_day& x, const month_day& y) noexcept;
 constexpr strong_ordering operator<=>(const month_day& x, const month_day& y) noexcept;
 
+template<class charT, class traits>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const month_day& md);
 
 // 25.8.10, class month_day_last    // C++20
 class month_day_last;
@@ -404,18 +415,30 @@ class month_day_last;
 constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept;
 constexpr strong_ordering operator<=>(const month_day_last& x, const month_day_last& y) noexcept;
 
+template<class charT, class traits>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const month_day_last& mdl);
+
 // 25.8.11, class month_weekday    // C++20
 class month_weekday;
 
 constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept;
 constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept;
 
+template<class charT, class traits>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const month_weekday& mwd);
+
 // 25.8.12, class month_weekday_last    // C++20
 class month_weekday_last;
 
 constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;
 constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept;
 
+template<class charT, class traits>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const month_weekday_last& mwdl);
+
 
 // 25.8.13, class year_month    // C++20
 class year_month;
@@ -431,6 +454,10 @@ constexpr year_month operator+(const year_month& ym, const years& dy) noexcept;
 constexpr year_month operator+(const years& dy, const year_month& ym) noexcept;
 constexpr year_month operator-(const year_month& ym, const years& dy) noexcept;
 
+template<class charT, class traits>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const year_month& ym);
+
 // 25.8.14, class year_month_day class    // C++20
 year_month_day;
 
@@ -444,6 +471,9 @@ constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) n
 constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept;
 constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
 
+template<class charT, class traits>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const year_month_day& ymd);
 
 // 25.8.15, class year_month_day_last    // C++20
 class year_month_day_last;
@@ -464,6 +494,10 @@ constexpr year_month_day_last
 constexpr year_month_day_last
   operator-(const year_month_day_last& ymdl, const years& dy) noexcept;
 
+template<class charT, class traits>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const year_month_day_last& ymdl);
+
 // 25.8.16, class year_month_weekday    // C++20
 class year_month_weekday;
 
@@ -485,6 +519,10 @@ constexpr year_month_weekday
 constexpr year_month_weekday
   operator-(const year_month_weekday& ymwd, const years& dy) noexcept;
 
+template<class charT, class traits>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const year_month_weekday& ymwd);
+
 // 25.8.17, class year_month_weekday_last    // C++20
 class year_month_weekday_last;
 
@@ -505,6 +543,10 @@ constexpr year_month_weekday_last
 constexpr year_month_weekday_last
   operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
 
+template<class charT, class traits>
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const year_month_weekday_last& ymwdl);
+
 // 25.8.18, civil calendar conventional syntax operators    // C++20
 constexpr year_month
   operator/(const year& y, const month& m) noexcept;
@@ -638,6 +680,17 @@ namespace std {
   template<class charT> struct formatter<chrono::month, charT>;                   // C++20
   template<class charT> struct formatter<chrono::year, charT>;                    // C++20
   template<class charT> struct formatter<chrono::weekday, charT>;                 // C++20
+  template<class charT> struct formatter<chrono::weekday_indexed, charT>;         // C++20
+  template<class charT> struct formatter<chrono::weekday_last, charT>;            // C++20
+  template<class charT> struct formatter<chrono::month_day, charT>;               // C++20
+  template<class charT> struct formatter<chrono::month_day_last, charT>;          // C++20
+  template<class charT> struct formatter<chrono::month_weekday, charT>;           // C++20
+  template<class charT> struct formatter<chrono::month_weekday_last, charT>;      // C++20
+  template<class charT> struct formatter<chrono::year_month, charT>;              // C++20
+  template<class charT> struct formatter<chrono::year_month_day, charT>;          // C++20
+  template<class charT> struct formatter<chrono::year_month_day_last, charT>;     // C++20
+  template<class charT> struct formatter<chrono::year_month_weekday, charT>;      // C++20
+  template<class charT> struct formatter<chrono::year_month_weekday_last, charT>; // C++20
 } // namespace std
 
 namespace chrono {

diff  --git a/libcxx/include/optional b/libcxx/include/optional
index a7a887a9cbdcc..6272f839c751f 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -1574,10 +1574,6 @@ _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER > 14
 
-#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
-#  include <chrono>
-#endif
-
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 #  include <atomic>
 #  include <climits>

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv
index 59ce001634445..b5c1e9831e4aa 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -47,7 +47,6 @@ array stdexcept
 array type_traits
 array utility
 array version
-atomic chrono
 atomic cmath
 atomic compare
 atomic cstddef
@@ -108,10 +107,15 @@ charconv limits
 charconv type_traits
 chrono compare
 chrono concepts
+chrono cstddef
 chrono cstdint
+chrono cstdlib
 chrono ctime
 chrono limits
 chrono ratio
+chrono stdexcept
+chrono string_view
+chrono tuple
 chrono type_traits
 chrono version
 cinttypes cstdint
@@ -597,7 +601,6 @@ numeric limits
 numeric type_traits
 numeric version
 optional atomic
-optional chrono
 optional climits
 optional compare
 optional concepts

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv
index dc68a6a7fcbe8..6880ba7aeac61 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -47,7 +47,6 @@ array stdexcept
 array type_traits
 array utility
 array version
-atomic chrono
 atomic cmath
 atomic compare
 atomic cstddef
@@ -108,10 +107,15 @@ charconv limits
 charconv type_traits
 chrono compare
 chrono concepts
+chrono cstddef
 chrono cstdint
+chrono cstdlib
 chrono ctime
 chrono limits
 chrono ratio
+chrono stdexcept
+chrono string_view
+chrono tuple
 chrono type_traits
 chrono version
 cinttypes cstdint
@@ -598,7 +602,6 @@ numeric limits
 numeric type_traits
 numeric version
 optional atomic
-optional chrono
 optional climits
 optional compare
 optional concepts

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index e517a60deebba..c6de5a8e10d2d 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -47,7 +47,6 @@ array stdexcept
 array type_traits
 array utility
 array version
-atomic chrono
 atomic cmath
 atomic compare
 atomic cstddef
@@ -108,10 +107,15 @@ charconv limits
 charconv type_traits
 chrono compare
 chrono concepts
+chrono cstddef
 chrono cstdint
+chrono cstdlib
 chrono ctime
 chrono limits
 chrono ratio
+chrono stdexcept
+chrono string_view
+chrono tuple
 chrono type_traits
 chrono version
 cinttypes cstdint
@@ -600,7 +604,6 @@ numeric limits
 numeric type_traits
 numeric version
 optional atomic
-optional chrono
 optional climits
 optional compare
 optional concepts

diff  --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index e517a60deebba..c6de5a8e10d2d 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -47,7 +47,6 @@ array stdexcept
 array type_traits
 array utility
 array version
-atomic chrono
 atomic cmath
 atomic compare
 atomic cstddef
@@ -108,10 +107,15 @@ charconv limits
 charconv type_traits
 chrono compare
 chrono concepts
+chrono cstddef
 chrono cstdint
+chrono cstdlib
 chrono ctime
 chrono limits
 chrono ratio
+chrono stdexcept
+chrono string_view
+chrono tuple
 chrono type_traits
 chrono version
 cinttypes cstdint
@@ -600,7 +604,6 @@ numeric limits
 numeric type_traits
 numeric version
 optional atomic
-optional chrono
 optional climits
 optional compare
 optional concepts

diff  --git a/libcxx/test/std/time/time.cal/time.cal.md/time.cal.md.nonmembers/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.md/time.cal.md.nonmembers/ostream.pass.cpp
new file mode 100644
index 0000000000000..4e4feda0c8091
--- /dev/null
+++ b/libcxx/test/std/time/time.cal/time.cal.md/time.cal.md.nonmembers/ostream.pass.cpp
@@ -0,0 +1,134 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+// class month_day;
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const month_day& md);
+
+#include <chrono>
+#include <cassert>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static std::basic_string<CharT> stream_c_locale(std::chrono::month_day md) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << md;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::month_day md) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_fr_FR_UTF_8);
+  sstr.imbue(locale);
+  sstr << md;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::month_day md) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_ja_JP_UTF_8);
+  sstr.imbue(locale);
+  sstr << md;
+  return sstr.str();
+}
+
+template <class CharT>
+static void test() {
+  using namespace std::literals::chrono_literals;
+
+  assert(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 0d}) ==
+         SV("0 is not a valid month/00 is not a valid day"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 1d}) == SV("0 is not a valid month/01"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}) ==
+         SV("Jan/255 is not a valid day"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}) == SV("Jan/31"));
+  // February is considered valid with 29 days; it lacks the year information
+  // to do a proper validation.
+  assert(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}) == SV("Feb/29"));
+  // The month_day stream operator has no validation, this means never validate
+  // dates don't get
+  //   Jun/31 is not a valid month day
+  // which is inconsistent with other stream operators.
+  // TODO FMT file an issue about this.
+  assert(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}) == SV("Jun/31"));
+
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 0d}) ==
+         SV("0 is not a valid month/00 is not a valid day"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 1d}) ==
+         SV("0 is not a valid month/01"));
+#if defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}) ==
+         SV("jan/255 is not a valid day"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}) == SV("jan/31"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}) == SV("fév/29"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}) == SV("jui/31"));
+#else  //  defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}) ==
+         SV("janv./255 is not a valid day"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}) == SV("janv./31"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}) == SV("févr./29"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}) == SV("juin/31"));
+#endif //  defined(__APPLE__)
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 0d}) ==
+         SV("0 is not a valid month/00 is not a valid day"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 1d}) ==
+         SV("0 is not a valid month/01"));
+#if defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}) ==
+         SV(" 1/255 is not a valid day"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}) == SV(" 1/31"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}) == SV(" 2/29"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}) == SV(" 6/31"));
+#elif defined(_AIX) || defined(_WIN32) //  defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}) ==
+         SV("1月/255 is not a valid day"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}) == SV("1月/31"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}) == SV("2月/29"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}) == SV("6月/31"));
+#else                                  //  defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}) ==
+         SV(" 1月/255 is not a valid day"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}) == SV(" 1月/31"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}) == SV(" 2月/29"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}) == SV(" 6月/31"));
+#endif                                 //  defined(__APPLE__)
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.cal/time.cal.mdlast/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.mdlast/ostream.pass.cpp
new file mode 100644
index 0000000000000..e6475f82d9fe5
--- /dev/null
+++ b/libcxx/test/std/time/time.cal/time.cal.mdlast/ostream.pass.cpp
@@ -0,0 +1,179 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// class month_day_last;
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const month_day_last& mdl);
+
+#include <chrono>
+#include <cassert>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static std::basic_string<CharT> stream_c_locale(std::chrono::month_day_last mdl) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << mdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::month_day_last mdl) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_fr_FR_UTF_8);
+  sstr.imbue(locale);
+  sstr << mdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::month_day_last mdl) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_ja_JP_UTF_8);
+  sstr.imbue(locale);
+  sstr << mdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static void test() {
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{0}}) ==
+         SV("0 is not a valid month/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{1}}) == SV("Jan/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{2}}) == SV("Feb/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{3}}) == SV("Mar/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{4}}) == SV("Apr/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{5}}) == SV("May/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{6}}) == SV("Jun/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{7}}) == SV("Jul/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{8}}) == SV("Aug/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{9}}) == SV("Sep/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{10}}) == SV("Oct/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{11}}) == SV("Nov/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{12}}) == SV("Dec/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{13}}) ==
+         SV("13 is not a valid month/last"));
+  assert(stream_c_locale<CharT>(std::chrono::month_day_last{std::chrono::month{255}}) ==
+         SV("255 is not a valid month/last"));
+
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{0}}) ==
+         SV("0 is not a valid month/last"));
+#if defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{1}}) == SV("jan/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{2}}) == SV("fév/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{3}}) == SV("mar/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{4}}) == SV("avr/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{5}}) == SV("mai/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{6}}) == SV("jui/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{7}}) == SV("jul/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{8}}) == SV("aoû/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{9}}) == SV("sep/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{10}}) == SV("oct/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{11}}) == SV("nov/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{12}}) == SV("déc/last"));
+#else //  defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{1}}) == SV("janv./last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{2}}) == SV("févr./last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{3}}) == SV("mars/last"));
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{4}}) == SV("avr./last"));
+#  else
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{4}}) == SV("avril/last"));
+#  endif
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{5}}) == SV("mai/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{6}}) == SV("juin/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{7}}) == SV("juil./last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{8}}) == SV("août/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{9}}) == SV("sept./last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{10}}) == SV("oct./last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{11}}) == SV("nov./last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{12}}) == SV("déc./last"));
+#endif //  defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{13}}) ==
+         SV("13 is not a valid month/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_day_last{std::chrono::month{255}}) ==
+         SV("255 is not a valid month/last"));
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{0}}) ==
+         SV("0 is not a valid month/last"));
+#if defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{1}}) == SV(" 1/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{2}}) == SV(" 2/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{3}}) == SV(" 3/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{4}}) == SV(" 4/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{5}}) == SV(" 5/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{6}}) == SV(" 6/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{7}}) == SV(" 7/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{8}}) == SV(" 8/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{9}}) == SV(" 9/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{10}}) == SV("10/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{11}}) == SV("11/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{12}}) == SV("12/last"));
+#else    // defined(__APPLE__)
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{1}}) == SV("1月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{2}}) == SV("2月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{3}}) == SV("3月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{4}}) == SV("4月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{5}}) == SV("5月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{6}}) == SV("6月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{7}}) == SV("7月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{8}}) == SV("8月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{9}}) == SV("9月/last"));
+#  else  // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{1}}) == SV(" 1月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{2}}) == SV(" 2月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{3}}) == SV(" 3月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{4}}) == SV(" 4月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{5}}) == SV(" 5月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{6}}) == SV(" 6月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{7}}) == SV(" 7月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{8}}) == SV(" 8月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{9}}) == SV(" 9月/last"));
+#  endif // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{10}}) == SV("10月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{11}}) == SV("11月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{12}}) == SV("12月/last"));
+#endif   // defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{13}}) ==
+         SV("13 is not a valid month/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_day_last{std::chrono::month{255}}) ==
+         SV("255 is not a valid month/last"));
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/ostream.pass.cpp
new file mode 100644
index 0000000000000..2c0e692c1af91
--- /dev/null
+++ b/libcxx/test/std/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/ostream.pass.cpp
@@ -0,0 +1,285 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// class month_weekday;
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const month_weekday& mwd);
+
+#include <chrono>
+#include <cassert>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static std::basic_string<CharT> stream_c_locale(std::chrono::month_weekday mwd) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << mwd;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::month_weekday mwd) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_fr_FR_UTF_8);
+  sstr.imbue(locale);
+  sstr << mwd;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::month_weekday mwd) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_ja_JP_UTF_8);
+  sstr.imbue(locale);
+  sstr << mwd;
+  return sstr.str();
+}
+
+template <class CharT>
+static void test() {
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) ==
+         SV("0 is not a valid month/Sun[1]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}}) == SV("Jan/Mon[1]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{2}, std::chrono::weekday_indexed{std::chrono::weekday{2}, 2}}) == SV("Feb/Tue[2]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{3}, std::chrono::weekday_indexed{std::chrono::weekday{3}, 3}}) == SV("Mar/Wed[3]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{4}, std::chrono::weekday_indexed{std::chrono::weekday{4}, 4}}) == SV("Apr/Thu[4]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{5}, std::chrono::weekday_indexed{std::chrono::weekday{5}, 5}}) == SV("May/Fri[5]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{6}, std::chrono::weekday_indexed{std::chrono::weekday{6}, 6}}) ==
+         SV("Jun/Sat[6 is not a valid index]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{7}, std::chrono::weekday_indexed{std::chrono::weekday{7}, 7}}) ==
+         SV("Jul/Sun[7 is not a valid index]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{8}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}}) ==
+         SV("Aug/8 is not a valid weekday[0 is not a valid index]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{9}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("Sep/Sun[1]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{10}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("Oct/Sun[1]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{11}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("Nov/Sun[1]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{12}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("Dec/Sun[1]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{13}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) ==
+         SV("13 is not a valid month/Sun[1]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{255}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}}) ==
+         SV("255 is not a valid month/8 is not a valid weekday[0 is not a valid index]"));
+
+#if defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) ==
+         SV("0 is not a valid month/Dim[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}}) == SV("jan/Lun[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{2}, std::chrono::weekday_indexed{std::chrono::weekday{2}, 2}}) == SV("fév/Mar[2]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{3}, std::chrono::weekday_indexed{std::chrono::weekday{3}, 3}}) == SV("mar/Mer[3]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{4}, std::chrono::weekday_indexed{std::chrono::weekday{4}, 4}}) == SV("avr/Jeu[4]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{5}, std::chrono::weekday_indexed{std::chrono::weekday{5}, 5}}) == SV("mai/Ven[5]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{6}, std::chrono::weekday_indexed{std::chrono::weekday{6}, 6}}) ==
+         SV("jui/Sam[6 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{7}, std::chrono::weekday_indexed{std::chrono::weekday{7}, 7}}) ==
+         SV("jul/Dim[7 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{8}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}}) ==
+         SV("aoû/8 is not a valid weekday[0 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{9}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("sep/Dim[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{10}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("oct/Dim[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{11}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("nov/Dim[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{12}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("déc/Dim[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{13}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) ==
+         SV("13 is not a valid month/Dim[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{255}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}}) ==
+         SV("255 is not a valid month/8 is not a valid weekday[0 is not a valid index]"));
+#else //  defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) ==
+         SV("0 is not a valid month/dim.[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}}) == SV("janv./lun.[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{2}, std::chrono::weekday_indexed{std::chrono::weekday{2}, 2}}) == SV("févr./mar.[2]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{3}, std::chrono::weekday_indexed{std::chrono::weekday{3}, 3}}) == SV("mars/mer.[3]"));
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{4}, std::chrono::weekday_indexed{std::chrono::weekday{4}, 4}}) == SV("avr./jeu.[4]"));
+#  else
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{4}, std::chrono::weekday_indexed{std::chrono::weekday{4}, 4}}) == SV("avril/jeu.[4]"));
+#  endif
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{5}, std::chrono::weekday_indexed{std::chrono::weekday{5}, 5}}) == SV("mai/ven.[5]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{6}, std::chrono::weekday_indexed{std::chrono::weekday{6}, 6}}) ==
+         SV("juin/sam.[6 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{7}, std::chrono::weekday_indexed{std::chrono::weekday{7}, 7}}) ==
+         SV("juil./dim.[7 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{8}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}}) ==
+         SV("août/8 is not a valid weekday[0 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{9}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("sept./dim.[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{10}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("oct./dim.[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{11}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("nov./dim.[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{12}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("déc./dim.[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{13}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) ==
+         SV("13 is not a valid month/dim.[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{255}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}}) ==
+         SV("255 is not a valid month/8 is not a valid weekday[0 is not a valid index]"));
+#endif //  defined(__APPLE__)
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) ==
+         SV("0 is not a valid month/日[1]"));
+#if defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}}) == SV(" 1/月[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{2}, std::chrono::weekday_indexed{std::chrono::weekday{2}, 2}}) == SV(" 2/火[2]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{3}, std::chrono::weekday_indexed{std::chrono::weekday{3}, 3}}) == SV(" 3/水[3]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{4}, std::chrono::weekday_indexed{std::chrono::weekday{4}, 4}}) == SV(" 4/木[4]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{5}, std::chrono::weekday_indexed{std::chrono::weekday{5}, 5}}) == SV(" 5/金[5]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{6}, std::chrono::weekday_indexed{std::chrono::weekday{6}, 6}}) ==
+         SV(" 6/土[6 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{7}, std::chrono::weekday_indexed{std::chrono::weekday{7}, 7}}) ==
+         SV(" 7/日[7 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{8}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}}) ==
+         SV(" 8/8 is not a valid weekday[0 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{9}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV(" 9/日[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{10}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("10/日[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{11}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("11/日[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{12}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("12/日[1]"));
+#else    // defined(__APPLE__)
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}}) == SV("1月/月[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{2}, std::chrono::weekday_indexed{std::chrono::weekday{2}, 2}}) == SV("2月/火[2]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{3}, std::chrono::weekday_indexed{std::chrono::weekday{3}, 3}}) == SV("3月/水[3]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{4}, std::chrono::weekday_indexed{std::chrono::weekday{4}, 4}}) == SV("4月/木[4]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{5}, std::chrono::weekday_indexed{std::chrono::weekday{5}, 5}}) == SV("5月/金[5]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{6}, std::chrono::weekday_indexed{std::chrono::weekday{6}, 6}}) ==
+         SV("6月/土[6 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{7}, std::chrono::weekday_indexed{std::chrono::weekday{7}, 7}}) ==
+         SV("7月/日[7 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{8}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}}) ==
+         SV("8月/8 is not a valid weekday[0 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{9}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("9月/日[1]"));
+#  else  // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}}) == SV(" 1月/月[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{2}, std::chrono::weekday_indexed{std::chrono::weekday{2}, 2}}) == SV(" 2月/火[2]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{3}, std::chrono::weekday_indexed{std::chrono::weekday{3}, 3}}) == SV(" 3月/水[3]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{4}, std::chrono::weekday_indexed{std::chrono::weekday{4}, 4}}) == SV(" 4月/木[4]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{5}, std::chrono::weekday_indexed{std::chrono::weekday{5}, 5}}) == SV(" 5月/金[5]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{6}, std::chrono::weekday_indexed{std::chrono::weekday{6}, 6}}) ==
+         SV(" 6月/土[6 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{7}, std::chrono::weekday_indexed{std::chrono::weekday{7}, 7}}) ==
+         SV(" 7月/日[7 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{8}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}}) ==
+         SV(" 8月/8 is not a valid weekday[0 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{9}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV(" 9月/日[1]"));
+#  endif // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{10}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("10月/日[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{11}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("11月/日[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{12}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) == SV("12月/日[1]"));
+#endif   // defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{13}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}}) ==
+         SV("13 is not a valid month/日[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday{
+             std::chrono::month{255}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}}) ==
+         SV("255 is not a valid month/8 is not a valid weekday[0 is not a valid index]"));
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/ostream.pass.cpp
new file mode 100644
index 0000000000000..ca3d71eddf3cc
--- /dev/null
+++ b/libcxx/test/std/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/ostream.pass.cpp
@@ -0,0 +1,276 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// class month_weekday_last;
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const month_weekday_last& mwdl);
+
+#include <chrono>
+#include <cassert>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static std::basic_string<CharT> stream_c_locale(std::chrono::month_weekday_last mwdl) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << mwdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::month_weekday_last mwdl) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_fr_FR_UTF_8);
+  sstr.imbue(locale);
+  sstr << mwdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::month_weekday_last mwdl) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_ja_JP_UTF_8);
+  sstr.imbue(locale);
+  sstr << mwdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static void test() {
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("0 is not a valid month/Sun[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("Jan/Sun[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{2}, std::chrono::weekday_last{std::chrono::weekday{1}}}) == SV("Feb/Mon[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{3}, std::chrono::weekday_last{std::chrono::weekday{2}}}) == SV("Mar/Tue[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{4}, std::chrono::weekday_last{std::chrono::weekday{3}}}) == SV("Apr/Wed[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{5}, std::chrono::weekday_last{std::chrono::weekday{4}}}) == SV("May/Thu[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{6}, std::chrono::weekday_last{std::chrono::weekday{5}}}) == SV("Jun/Fri[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{7}, std::chrono::weekday_last{std::chrono::weekday{6}}}) == SV("Jul/Sat[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{8}, std::chrono::weekday_last{std::chrono::weekday{7}}}) == SV("Aug/Sun[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{9}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("Sep/8 is not a valid weekday[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{10}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("Oct/Sun[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{11}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("Nov/Sun[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{12}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("Dec/Sun[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{13}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("13 is not a valid month/Sun[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{255}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("255 is not a valid month/8 is not a valid weekday[last]"));
+
+#if defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("0 is not a valid month/Dim[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("jan/Dim[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{2}, std::chrono::weekday_last{std::chrono::weekday{1}}}) == SV("fév/Lun[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{3}, std::chrono::weekday_last{std::chrono::weekday{2}}}) == SV("mar/Mar[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{4}, std::chrono::weekday_last{std::chrono::weekday{3}}}) == SV("avr/Mer[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{5}, std::chrono::weekday_last{std::chrono::weekday{4}}}) == SV("mai/Jeu[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{6}, std::chrono::weekday_last{std::chrono::weekday{5}}}) == SV("jui/Ven[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{7}, std::chrono::weekday_last{std::chrono::weekday{6}}}) == SV("jul/Sam[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{8}, std::chrono::weekday_last{std::chrono::weekday{7}}}) == SV("aoû/Dim[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{9}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("sep/8 is not a valid weekday[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{10}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("oct/Dim[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{11}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("nov/Dim[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{12}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("déc/Dim[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{13}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("13 is not a valid month/Dim[last]"));
+#else    //  defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("0 is not a valid month/dim.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("janv./dim.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{2}, std::chrono::weekday_last{std::chrono::weekday{1}}}) == SV("févr./lun.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{3}, std::chrono::weekday_last{std::chrono::weekday{2}}}) == SV("mars/mar.[last]"));
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{4}, std::chrono::weekday_last{std::chrono::weekday{3}}}) == SV("avr./mer.[last]"));
+#  else  // defined(_WIN32) || defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{4}, std::chrono::weekday_last{std::chrono::weekday{3}}}) == SV("avril/mer.[last]"));
+#  endif // defined(_WIN32) || defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{5}, std::chrono::weekday_last{std::chrono::weekday{4}}}) == SV("mai/jeu.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{6}, std::chrono::weekday_last{std::chrono::weekday{5}}}) == SV("juin/ven.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{7}, std::chrono::weekday_last{std::chrono::weekday{6}}}) == SV("juil./sam.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{8}, std::chrono::weekday_last{std::chrono::weekday{7}}}) == SV("août/dim.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{9}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("sept./8 is not a valid weekday[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{10}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("oct./dim.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{11}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("nov./dim.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{12}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("déc./dim.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{13}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("13 is not a valid month/dim.[last]"));
+#endif   //  defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{255}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("255 is not a valid month/8 is not a valid weekday[last]"));
+
+#if defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("0 is not a valid month/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV(" 1/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{2}, std::chrono::weekday_last{std::chrono::weekday{1}}}) == SV(" 2/月[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{3}, std::chrono::weekday_last{std::chrono::weekday{2}}}) == SV(" 3/火[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{4}, std::chrono::weekday_last{std::chrono::weekday{3}}}) == SV(" 4/水[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{5}, std::chrono::weekday_last{std::chrono::weekday{4}}}) == SV(" 5/木[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{6}, std::chrono::weekday_last{std::chrono::weekday{5}}}) == SV(" 6/金[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{7}, std::chrono::weekday_last{std::chrono::weekday{6}}}) == SV(" 7/土[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{8}, std::chrono::weekday_last{std::chrono::weekday{7}}}) == SV(" 8/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{9}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV(" 9/8 is not a valid weekday[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{10}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("10/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{11}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("11/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{12}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("12/日[last]"));
+#else    // defined(__APPLE__)
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("0 is not a valid month/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("1月/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{2}, std::chrono::weekday_last{std::chrono::weekday{1}}}) == SV("2月/月[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{3}, std::chrono::weekday_last{std::chrono::weekday{2}}}) == SV("3月/火[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{4}, std::chrono::weekday_last{std::chrono::weekday{3}}}) == SV("4月/水[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{5}, std::chrono::weekday_last{std::chrono::weekday{4}}}) == SV("5月/木[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{6}, std::chrono::weekday_last{std::chrono::weekday{5}}}) == SV("6月/金[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{7}, std::chrono::weekday_last{std::chrono::weekday{6}}}) == SV("7月/土[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{8}, std::chrono::weekday_last{std::chrono::weekday{7}}}) == SV("8月/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{9}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("9月/8 is not a valid weekday[last]"));
+#  else  // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("0 is not a valid month/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV(" 1月/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{2}, std::chrono::weekday_last{std::chrono::weekday{1}}}) == SV(" 2月/月[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{3}, std::chrono::weekday_last{std::chrono::weekday{2}}}) == SV(" 3月/火[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{4}, std::chrono::weekday_last{std::chrono::weekday{3}}}) == SV(" 4月/水[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{5}, std::chrono::weekday_last{std::chrono::weekday{4}}}) == SV(" 5月/木[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{6}, std::chrono::weekday_last{std::chrono::weekday{5}}}) == SV(" 6月/金[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{7}, std::chrono::weekday_last{std::chrono::weekday{6}}}) == SV(" 7月/土[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{8}, std::chrono::weekday_last{std::chrono::weekday{7}}}) == SV(" 8月/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{9}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV(" 9月/8 is not a valid weekday[last]"));
+#  endif // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{10}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("10月/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{11}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("11月/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{12}, std::chrono::weekday_last{std::chrono::weekday{0}}}) == SV("12月/日[last]"));
+#endif   // defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{13}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("13 is not a valid month/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::month_weekday_last{
+             std::chrono::month{255}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("255 is not a valid month/8 is not a valid weekday[last]"));
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/ostream.pass.cpp
new file mode 100644
index 0000000000000..7a59350ffea10
--- /dev/null
+++ b/libcxx/test/std/time/time.cal/time.cal.wdidx/time.cal.wdidx.nonmembers/ostream.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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+// class weekday_indexed;
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const weekday_indexed& wdi);
+
+#include <chrono>
+#include <cassert>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static std::basic_string<CharT> stream_c_locale(std::chrono::weekday_indexed wdi) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << wdi;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::weekday_indexed wdi) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_fr_FR_UTF_8);
+  sstr.imbue(locale);
+  sstr << wdi;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::weekday_indexed wdi) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_ja_JP_UTF_8);
+  sstr.imbue(locale);
+  sstr << wdi;
+  return sstr.str();
+}
+
+template <class CharT>
+static void test() {
+  assert(stream_c_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(0), 1}) == SV("Sun[1]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(1), 2}) == SV("Mon[2]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(2), 3}) == SV("Tue[3]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(3), 4}) == SV("Wed[4]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(4), 5}) == SV("Thu[5]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(5), 0}) ==
+         SV("Fri[0 is not a valid index]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(6), 6}) ==
+         SV("Sat[6 is not a valid index]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(7), 7}) ==
+         SV("Sun[7 is not a valid index]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(8), 0}) ==
+         SV("8 is not a valid weekday[0 is not a valid index]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(255), 1}) ==
+         SV("255 is not a valid weekday[1]"));
+
+#if defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(0), 1}) == SV("Dim[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(1), 2}) == SV("Lun[2]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(2), 3}) == SV("Mar[3]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(3), 4}) == SV("Mer[4]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(4), 5}) == SV("Jeu[5]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(5), 0}) ==
+         SV("Ven[0 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(6), 6}) ==
+         SV("Sam[6 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(7), 7}) ==
+         SV("Dim[7 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(255), 1}) ==
+         SV("255 is not a valid weekday[1]"));
+#else  // defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(0), 1}) == SV("dim.[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(1), 2}) == SV("lun.[2]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(2), 3}) == SV("mar.[3]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(3), 4}) == SV("mer.[4]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(4), 5}) == SV("jeu.[5]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(5), 0}) ==
+         SV("ven.[0 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(6), 6}) ==
+         SV("sam.[6 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(7), 7}) ==
+         SV("dim.[7 is not a valid index]"));
+#endif // defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(8), 0}) ==
+         SV("8 is not a valid weekday[0 is not a valid index]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(255), 1}) ==
+         SV("255 is not a valid weekday[1]"));
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(0), 1}) == SV("日[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(1), 2}) == SV("月[2]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(2), 3}) == SV("火[3]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(3), 4}) == SV("水[4]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(4), 5}) == SV("木[5]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(5), 0}) ==
+         SV("金[0 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(6), 6}) ==
+         SV("土[6 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(7), 7}) ==
+         SV("日[7 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(8), 0}) ==
+         SV("8 is not a valid weekday[0 is not a valid index]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_indexed{std::chrono::weekday(255), 1}) ==
+         SV("255 is not a valid weekday[1]"));
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/ostream.pass.cpp
new file mode 100644
index 0000000000000..90dca782880a5
--- /dev/null
+++ b/libcxx/test/std/time/time.cal/time.cal.wdlast/time.cal.wdlast.nonmembers/ostream.pass.cpp
@@ -0,0 +1,122 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+// class weekday_last;
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const weekday_last& wdl);
+
+#include <chrono>
+#include <cassert>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static std::basic_string<CharT> stream_c_locale(std::chrono::weekday_last wdl) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << wdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::weekday_last wdl) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_fr_FR_UTF_8);
+  sstr.imbue(locale);
+  sstr << wdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::weekday_last wdl) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_ja_JP_UTF_8);
+  sstr.imbue(locale);
+  sstr << wdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static void test() {
+  assert(stream_c_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{0}}) == SV("Sun[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{1}}) == SV("Mon[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{2}}) == SV("Tue[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{3}}) == SV("Wed[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{4}}) == SV("Thu[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{5}}) == SV("Fri[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{6}}) == SV("Sat[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{7}}) == SV("Sun[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{8}}) ==
+         SV("8 is not a valid weekday[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{255}}) ==
+         SV("255 is not a valid weekday[last]"));
+
+#if defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{0}}) == SV("Dim[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{1}}) == SV("Lun[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{2}}) == SV("Mar[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{3}}) == SV("Mer[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{4}}) == SV("Jeu[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{5}}) == SV("Ven[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{6}}) == SV("Sam[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{7}}) == SV("Dim[last]"));
+#else  // defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{0}}) == SV("dim.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{1}}) == SV("lun.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{2}}) == SV("mar.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{3}}) == SV("mer.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{4}}) == SV("jeu.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{5}}) == SV("ven.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{6}}) == SV("sam.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{7}}) == SV("dim.[last]"));
+#endif // defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{8}}) ==
+         SV("8 is not a valid weekday[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{255}}) ==
+         SV("255 is not a valid weekday[last]"));
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{0}}) == SV("日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{1}}) == SV("月[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{2}}) == SV("火[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{3}}) == SV("水[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{4}}) == SV("木[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{5}}) == SV("金[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{6}}) == SV("土[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{7}}) == SV("日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{8}}) ==
+         SV("8 is not a valid weekday[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::weekday_last{std::chrono::weekday{255}}) ==
+         SV("255 is not a valid weekday[last]"));
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/ostream.pass.cpp
new file mode 100644
index 0000000000000..45ce90c6e8afc
--- /dev/null
+++ b/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/ostream.pass.cpp
@@ -0,0 +1,249 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// class year_month;
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const year_month& ym);
+
+#include <chrono>
+#include <cassert>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static std::basic_string<CharT> stream_c_locale(std::chrono::year_month ym) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << ym;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::year_month ym) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_fr_FR_UTF_8);
+  sstr.imbue(locale);
+  sstr << ym;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::year_month ym) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_ja_JP_UTF_8);
+  sstr.imbue(locale);
+  sstr << ym;
+  return sstr.str();
+}
+
+template <class CharT>
+static void test() {
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{0}}) ==
+         SV("-32768 is not a valid year/0 is not a valid month"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{1}}) ==
+         SV("-32768 is not a valid year/Jan"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'767}, std::chrono::month{2}}) ==
+         SV("-32767/Feb"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{3}}) ==
+         SV("0000/Mar"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{4}}) ==
+         SV("1970/Apr"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{32'767}, std::chrono::month{5}}) ==
+         SV("32767/May"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{6}}) ==
+         SV("0000/Jun"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{7}}) ==
+         SV("0000/Jul"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{8}}) ==
+         SV("0000/Aug"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{9}}) ==
+         SV("0000/Sep"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{10}}) ==
+         SV("0000/Oct"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{11}}) ==
+         SV("0000/Nov"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{12}}) ==
+         SV("0000/Dec"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{13}}) ==
+         SV("0000/13 is not a valid month"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{255}}) ==
+         SV("-32768 is not a valid year/255 is not a valid month"));
+
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{0}}) ==
+         SV("-32768 is not a valid year/0 is not a valid month"));
+#if defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{1}}) ==
+         SV("-32768 is not a valid year/jan"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'767}, std::chrono::month{2}}) ==
+         SV("-32767/fév"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{3}}) ==
+         SV("0000/mar"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{4}}) ==
+         SV("1970/avr"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{32'767}, std::chrono::month{5}}) ==
+         SV("32767/mai"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{6}}) ==
+         SV("0000/jui"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{7}}) ==
+         SV("0000/jul"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{8}}) ==
+         SV("0000/aoû"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{9}}) ==
+         SV("0000/sep"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{10}}) ==
+         SV("0000/oct"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{11}}) ==
+         SV("0000/nov"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{12}}) ==
+         SV("0000/déc"));
+#else    //  defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{1}}) ==
+         SV("-32768 is not a valid year/janv."));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'767}, std::chrono::month{2}}) ==
+         SV("-32767/févr."));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{3}}) ==
+         SV("0000/mars"));
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{4}}) ==
+         SV("1970/avr."));
+#  else  // defined(_WIN32) || defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{4}}) ==
+         SV("1970/avril"));
+#  endif // defined(_WIN32) || defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{32'767}, std::chrono::month{5}}) ==
+         SV("32767/mai"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{6}}) ==
+         SV("0000/juin"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{7}}) ==
+         SV("0000/juil."));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{8}}) ==
+         SV("0000/août"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{9}}) ==
+         SV("0000/sept."));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{10}}) ==
+         SV("0000/oct."));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{11}}) ==
+         SV("0000/nov."));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{12}}) ==
+         SV("0000/déc."));
+#endif   //  defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{13}}) ==
+         SV("0000/13 is not a valid month"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{255}}) ==
+         SV("-32768 is not a valid year/255 is not a valid month"));
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{0}}) ==
+         SV("-32768 is not a valid year/0 is not a valid month"));
+#if defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{1}}) ==
+         SV("-32768 is not a valid year/ 1"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'767}, std::chrono::month{2}}) ==
+         SV("-32767/ 2"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{3}}) ==
+         SV("0000/ 3"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{4}}) ==
+         SV("1970/ 4"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{32'767}, std::chrono::month{5}}) ==
+         SV("32767/ 5"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{6}}) ==
+         SV("0000/ 6"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{7}}) ==
+         SV("0000/ 7"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{8}}) ==
+         SV("0000/ 8"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{9}}) ==
+         SV("0000/ 9"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{10}}) ==
+         SV("0000/10"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{11}}) ==
+         SV("0000/11"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{12}}) ==
+         SV("0000/12"));
+#else    // defined(__APPLE__)
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{1}}) ==
+         SV("-32768 is not a valid year/1月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'767}, std::chrono::month{2}}) ==
+         SV("-32767/2月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{3}}) ==
+         SV("0000/3月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{4}}) ==
+         SV("1970/4月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{32'767}, std::chrono::month{5}}) ==
+         SV("32767/5月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{6}}) ==
+         SV("0000/6月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{7}}) ==
+         SV("0000/7月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{8}}) ==
+         SV("0000/8月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{9}}) ==
+         SV("0000/9月"));
+#  else  // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{1}}) ==
+         SV("-32768 is not a valid year/ 1月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'767}, std::chrono::month{2}}) ==
+         SV("-32767/ 2月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{3}}) ==
+         SV("0000/ 3月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{4}}) ==
+         SV("1970/ 4月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{32'767}, std::chrono::month{5}}) ==
+         SV("32767/ 5月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{6}}) ==
+         SV("0000/ 6月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{7}}) ==
+         SV("0000/ 7月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{8}}) ==
+         SV("0000/ 8月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{9}}) ==
+         SV("0000/ 9月"));
+#  endif // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{10}}) ==
+         SV("0000/10月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{11}}) ==
+         SV("0000/11月"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{12}}) ==
+         SV("0000/12月"));
+#endif   // defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{0}, std::chrono::month{13}}) ==
+         SV("0000/13 is not a valid month"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month{std::chrono::year{-32'768}, std::chrono::month{255}}) ==
+         SV("-32768 is not a valid year/255 is not a valid month"));
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/ostream.pass.cpp
new file mode 100644
index 0000000000000..595e00f0008c8
--- /dev/null
+++ b/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/ostream.pass.cpp
@@ -0,0 +1,149 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// class year_month_day;
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const year_month_day& ymd);
+
+#include <chrono>
+#include <cassert>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static std::basic_string<CharT> stream_c_locale(std::chrono::year_month_day ymd) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << ymd;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::year_month_day ymd) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_fr_FR_UTF_8);
+  sstr.imbue(locale);
+  sstr << ymd;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::year_month_day ymd) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_ja_JP_UTF_8);
+  sstr.imbue(locale);
+  sstr << ymd;
+  return sstr.str();
+}
+
+template <class CharT>
+static void test() {
+  assert(stream_c_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::day{1}}) ==
+         SV("-32768-01-01 is not a valid date"));
+  assert(stream_c_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::day{1}}) ==
+         SV("-32767-00-01 is not a valid date"));
+  assert(stream_c_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::day{0}}) ==
+         SV("-32767-01-00 is not a valid date"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{1}}) == SV("1970-01-01"));
+  assert(stream_c_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{1999}, std::chrono::month{2}, std::chrono::day{29}}) ==
+         SV("1999-02-29 is not a valid date"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}) == SV("2000-02-29"));
+
+#if defined(_AIX)
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}) == SV("+32767-12-31"));
+#else  // defined(_AIX)
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}) == SV("32767-12-31"));
+#endif // defined(_AIX)
+
+  assert(stream_fr_FR_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::day{1}}) ==
+         SV("-32768-01-01 is not a valid date"));
+  assert(stream_fr_FR_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::day{1}}) ==
+         SV("-32767-00-01 is not a valid date"));
+  assert(stream_fr_FR_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::day{0}}) ==
+         SV("-32767-01-00 is not a valid date"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{1}}) == SV("1970-01-01"));
+  assert(stream_fr_FR_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{1999}, std::chrono::month{2}, std::chrono::day{29}}) ==
+         SV("1999-02-29 is not a valid date"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}) == SV("2000-02-29"));
+#if defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}) == SV("+32767-12-31"));
+#else  // defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}) == SV("32767-12-31"));
+#endif // defined(_AIX)
+
+  assert(stream_ja_JP_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::day{1}}) ==
+         SV("-32768-01-01 is not a valid date"));
+  assert(stream_ja_JP_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::day{1}}) ==
+         SV("-32767-00-01 is not a valid date"));
+  assert(stream_ja_JP_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::day{0}}) ==
+         SV("-32767-01-00 is not a valid date"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{1}}) == SV("1970-01-01"));
+  assert(stream_ja_JP_locale<CharT>(
+             std::chrono::year_month_day{std::chrono::year{1999}, std::chrono::month{2}, std::chrono::day{29}}) ==
+         SV("1999-02-29 is not a valid date"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}) == SV("2000-02-29"));
+#if defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}) == SV("+32767-12-31"));
+#else  // defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day{
+             std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}) == SV("32767-12-31"));
+#endif // defined(_AIX)
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/ostream.pass.cpp
new file mode 100644
index 0000000000000..df75711b6e078
--- /dev/null
+++ b/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/ostream.pass.cpp
@@ -0,0 +1,266 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// class year_month_day_last;
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const year_month_day_last& ymdl);
+
+#include <chrono>
+#include <cassert>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static std::basic_string<CharT> stream_c_locale(std::chrono::year_month_day_last ymdl) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << ymdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::year_month_day_last ymdl) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_fr_FR_UTF_8);
+  sstr.imbue(locale);
+  sstr << ymdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::year_month_day_last ymdl) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_ja_JP_UTF_8);
+  sstr.imbue(locale);
+  sstr << ymdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static void test() {
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{0}}}) ==
+         SV("0000/0 is not a valid month/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'768}, std::chrono::month_day_last{std::chrono::month{1}}}) ==
+         SV("-32768 is not a valid year/Jan/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'767}, std::chrono::month_day_last{std::chrono::month{2}}}) == SV("-32767/Feb/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{3}}}) == SV("0000/Mar/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{4}}}) == SV("1970/Apr/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{32'767}, std::chrono::month_day_last{std::chrono::month{5}}}) == SV("32767/May/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{6}}}) == SV("0000/Jun/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{7}}}) == SV("0000/Jul/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{8}}}) == SV("0000/Aug/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{9}}}) == SV("0000/Sep/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{10}}}) == SV("0000/Oct/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{11}}}) == SV("0000/Nov/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{12}}}) == SV("0000/Dec/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{13}}}) ==
+         SV("0000/13 is not a valid month/last"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'768}, std::chrono::month_day_last{std::chrono::month{255}}}) ==
+         SV("-32768 is not a valid year/255 is not a valid month/last"));
+
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{0}}}) ==
+         SV("0000/0 is not a valid month/last"));
+#if defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'768}, std::chrono::month_day_last{std::chrono::month{1}}}) ==
+         SV("-32768 is not a valid year/jan/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'767}, std::chrono::month_day_last{std::chrono::month{2}}}) == SV("-32767/fév/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{3}}}) == SV("0000/mar/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{4}}}) == SV("1970/avr/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{32'767}, std::chrono::month_day_last{std::chrono::month{5}}}) == SV("32767/mai/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{6}}}) == SV("0000/jui/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{7}}}) == SV("0000/jul/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{8}}}) == SV("0000/aoû/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{9}}}) == SV("0000/sep/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{10}}}) == SV("0000/oct/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{11}}}) == SV("0000/nov/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{12}}}) == SV("0000/déc/last"));
+#else    //  defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'768}, std::chrono::month_day_last{std::chrono::month{1}}}) ==
+         SV("-32768 is not a valid year/janv./last"));
+  assert(
+      stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+          std::chrono::year{-32'767}, std::chrono::month_day_last{std::chrono::month{2}}}) == SV("-32767/févr./last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{3}}}) == SV("0000/mars/last"));
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{4}}}) == SV("1970/avr./last"));
+#  else  // defined(_WIN32) || defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{4}}}) == SV("1970/avril/last"));
+#  endif // defined(_WIN32) || defined(_AIX)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{32'767}, std::chrono::month_day_last{std::chrono::month{5}}}) == SV("32767/mai/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{6}}}) == SV("0000/juin/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{7}}}) == SV("0000/juil./last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{8}}}) == SV("0000/août/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{9}}}) == SV("0000/sept./last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{10}}}) == SV("0000/oct./last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{11}}}) == SV("0000/nov./last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{12}}}) == SV("0000/déc./last"));
+#endif   //  defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{13}}}) ==
+         SV("0000/13 is not a valid month/last"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'768}, std::chrono::month_day_last{std::chrono::month{255}}}) ==
+         SV("-32768 is not a valid year/255 is not a valid month/last"));
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{0}}}) ==
+         SV("0000/0 is not a valid month/last"));
+#if defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'768}, std::chrono::month_day_last{std::chrono::month{1}}}) ==
+         SV("-32768 is not a valid year/ 1/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'767}, std::chrono::month_day_last{std::chrono::month{2}}}) == SV("-32767/ 2/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{3}}}) == SV("0000/ 3/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{4}}}) == SV("1970/ 4/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{32'767}, std::chrono::month_day_last{std::chrono::month{5}}}) == SV("32767/ 5/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{6}}}) == SV("0000/ 6/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{7}}}) == SV("0000/ 7/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{8}}}) == SV("0000/ 8/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{9}}}) == SV("0000/ 9/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{10}}}) == SV("0000/10/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{11}}}) == SV("0000/11/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{12}}}) == SV("0000/12/last"));
+#else    // defined(__APPLE__)
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'768}, std::chrono::month_day_last{std::chrono::month{1}}}) ==
+         SV("-32768 is not a valid year/1月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'767}, std::chrono::month_day_last{std::chrono::month{2}}}) == SV("-32767/2月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{3}}}) == SV("0000/3月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{4}}}) == SV("1970/4月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{32'767}, std::chrono::month_day_last{std::chrono::month{5}}}) == SV("32767/5月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{6}}}) == SV("0000/6月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{7}}}) == SV("0000/7月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{8}}}) == SV("0000/8月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{9}}}) == SV("0000/9月/last"));
+#  else  // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'768}, std::chrono::month_day_last{std::chrono::month{1}}}) ==
+         SV("-32768 is not a valid year/ 1月/last"));
+  assert(
+      stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+          std::chrono::year{-32'767}, std::chrono::month_day_last{std::chrono::month{2}}}) == SV("-32767/ 2月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{3}}}) == SV("0000/ 3月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{4}}}) == SV("1970/ 4月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{32'767}, std::chrono::month_day_last{std::chrono::month{5}}}) == SV("32767/ 5月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{6}}}) == SV("0000/ 6月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{7}}}) == SV("0000/ 7月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{8}}}) == SV("0000/ 8月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{9}}}) == SV("0000/ 9月/last"));
+#  endif // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{10}}}) == SV("0000/10月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{11}}}) == SV("0000/11月/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{12}}}) == SV("0000/12月/last"));
+#endif   // defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{0}, std::chrono::month_day_last{std::chrono::month{13}}}) ==
+         SV("0000/13 is not a valid month/last"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_day_last{
+             std::chrono::year{-32'768}, std::chrono::month_day_last{std::chrono::month{255}}}) ==
+         SV("-32768 is not a valid year/255 is not a valid month/last"));
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/ostream.pass.cpp
new file mode 100644
index 0000000000000..05578f6c2397b
--- /dev/null
+++ b/libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/ostream.pass.cpp
@@ -0,0 +1,251 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// class year_month_weekday;
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const year_month_weekday& ymwd);
+
+#include <chrono>
+#include <cassert>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static std::basic_string<CharT> stream_c_locale(std::chrono::year_month_weekday ymwd) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << ymwd;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::year_month_weekday ymwd) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_fr_FR_UTF_8);
+  sstr.imbue(locale);
+  sstr << ymwd;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::year_month_weekday ymwd) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_ja_JP_UTF_8);
+  sstr.imbue(locale);
+  sstr << ymwd;
+  return sstr.str();
+}
+
+template <class CharT>
+static void test() {
+  assert(stream_c_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'768},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32768 is not a valid year/Jan/Sun[1]"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{0},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/0 is not a valid month/Sun[1]"));
+  assert(
+      stream_c_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{-32'767},
+          std::chrono::month{1},
+          std::chrono::weekday_indexed{std::chrono::weekday(8), 1}}) == SV("-32767/Jan/8 is not a valid weekday[1]"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 0}}) ==
+         SV("-32767/Jan/Sun[0 is not a valid index]")); // note 0 is a valid index here...
+  assert(stream_c_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/Jan/Sun[1]"));
+
+  assert(
+      stream_c_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) ==
+      SV("1970/Jan/Sun[1]"));
+
+#if defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'768},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32768 is not a valid year/jan/Dim[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{0},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/0 is not a valid month/Dim[1]"));
+  assert(
+      stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{-32'767},
+          std::chrono::month{1},
+          std::chrono::weekday_indexed{std::chrono::weekday(8), 1}}) == SV("-32767/jan/8 is not a valid weekday[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 0}}) ==
+         SV("-32767/jan/Dim[0 is not a valid index]")); // note 0 is a valid index here...
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/jan/Dim[1]"));
+
+  assert(
+      stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) ==
+      SV("1970/jan/Dim[1]"));
+#else  //  defined(__APPLE__)
+  assert(
+      stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{-32'768},
+          std::chrono::month{1},
+          std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32768 is not a valid year/janv./dim.[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{0},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/0 is not a valid month/dim.[1]"));
+  assert(
+      stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{-32'767},
+          std::chrono::month{1},
+          std::chrono::weekday_indexed{std::chrono::weekday(8), 1}}) == SV("-32767/janv./8 is not a valid weekday[1]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 0}}) ==
+         SV("-32767/janv./dim.[0 is not a valid index]")); // note 0 is a valid index here...
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/janv./dim.[1]"));
+
+  assert(
+      stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) ==
+      SV("1970/janv./dim.[1]"));
+#endif //  defined(__APPLE__)
+
+#if defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'768},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32768 is not a valid year/ 1/日[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{0},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/0 is not a valid month/日[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(8), 1}}) == SV("-32767/ 1/8 is not a valid weekday[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 0}}) ==
+         SV("-32767/ 1/日[0 is not a valid index]")); // note 0 is a valid index here...
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/ 1/日[1]"));
+
+  assert(
+      stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) ==
+      SV("1970/ 1/日[1]"));
+#else    // defined(__APPLE__)
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'768},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32768 is not a valid year/1月/日[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{0},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/0 is not a valid month/日[1]"));
+  assert(
+      stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{-32'767},
+          std::chrono::month{1},
+          std::chrono::weekday_indexed{std::chrono::weekday(8), 1}}) == SV("-32767/1月/8 is not a valid weekday[1]"));
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 0}}) ==
+         SV("-32767/1月/日[0 is not a valid index]")); // note 0 is a valid index here...
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/1月/日[1]"));
+
+  assert(
+      stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) ==
+      SV("1970/1月/日[1]"));
+#  else  // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'768},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32768 is not a valid year/ 1月/日[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{0},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/0 is not a valid month/日[1]"));
+  assert(
+      stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{-32'767},
+          std::chrono::month{1},
+          std::chrono::weekday_indexed{std::chrono::weekday(8), 1}}) == SV("-32767/ 1月/8 is not a valid weekday[1]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 0}}) ==
+         SV("-32767/ 1月/日[0 is not a valid index]")); // note 0 is a valid index here...
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+             std::chrono::year{-32'767},
+             std::chrono::month{1},
+             std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) == SV("-32767/ 1月/日[1]"));
+
+  assert(
+      stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday(0), 1}}) ==
+      SV("1970/ 1月/日[1]"));
+#  endif // defined(_WIN32) || defined(_AIX)
+#endif   // defined(__APPLE__)
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/ostream.pass.cpp
new file mode 100644
index 0000000000000..150813379e276
--- /dev/null
+++ b/libcxx/test/std/time/time.cal/time.cal.ymwdlast/time.cal.ymwdlast.nonmembers/ostream.pass.cpp
@@ -0,0 +1,185 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// class year_month_weekday_last;
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const year_month_weekday_last& ymwdl);
+
+#include <chrono>
+#include <cassert>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static std::basic_string<CharT> stream_c_locale(std::chrono::year_month_weekday_last ymwdl) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << ymwdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::year_month_weekday_last ymwdl) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_fr_FR_UTF_8);
+  sstr.imbue(locale);
+  sstr << ymwdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::year_month_weekday_last ymwdl) {
+  std::basic_stringstream<CharT> sstr;
+  const std::locale locale(LOCALE_ja_JP_UTF_8);
+  sstr.imbue(locale);
+  sstr << ymwdl;
+  return sstr.str();
+}
+
+template <class CharT>
+static void test() {
+  assert(stream_c_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32768 is not a valid year/Jan/Sun[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/0 is not a valid month/Sun[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("-32767/Jan/8 is not a valid weekday[last]"));
+  assert(stream_c_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/Jan/Sun[last]"));
+
+  assert(stream_c_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("1970/Jan/Sun[last]"));
+
+#if defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32768 is not a valid year/jan/Dim[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/0 is not a valid month/Dim[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("-32767/jan/8 is not a valid weekday[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/jan/Dim[last]"));
+
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("1970/jan/Dim[last]"));
+#else  //  defined(__APPLE__)
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32768 is not a valid year/janv./dim.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/0 is not a valid month/dim.[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("-32767/janv./8 is not a valid weekday[last]"));
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/janv./dim.[last]"));
+
+  assert(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("1970/janv./dim.[last]"));
+#endif //  defined(__APPLE__)
+
+#if defined(__APPLE__)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32768 is not a valid year/ 1/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/0 is not a valid month/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("-32767/ 1/8 is not a valid weekday[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/ 1/日[last]"));
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("1970/ 1/日[last]"));
+#else    // defined(__APPLE__)
+#  if defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32768 is not a valid year/1月/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/0 is not a valid month/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("-32767/1月/8 is not a valid weekday[last]"));
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/1月/日[last]"));
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("1970/1月/日[last]"));
+#  else  // defined(_WIN32) || defined(_AIX)
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32768 is not a valid year/ 1月/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/0 is not a valid month/日[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}) ==
+         SV("-32767/ 1月/8 is not a valid weekday[last]"));
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("-32767/ 1月/日[last]"));
+
+  assert(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
+             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}) ==
+         SV("1970/ 1月/日[last]"));
+#  endif // defined(_WIN32) || defined(_AIX)
+#endif   // defined(__APPLE__)
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.syn/formatter.month_day.pass.cpp b/libcxx/test/std/time/time.syn/formatter.month_day.pass.cpp
new file mode 100644
index 0000000000000..36550e78ceca8
--- /dev/null
+++ b/libcxx/test/std/time/time.syn/formatter.month_day.pass.cpp
@@ -0,0 +1,489 @@
+//===----------------------------------------------------------------------===//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// template<class charT> struct formatter<chrono::month_day, charT>;
+
+#include <chrono>
+#include <format>
+
+#include <cassert>
+#include <concepts>
+#include <locale>
+#include <iostream>
+#include <type_traits>
+
+#include "formatter_tests.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "string_literal.h"
+#include "test_macros.h"
+
+template <class CharT>
+static void test_no_chrono_specs() {
+  // Valid month "valid" day
+  check(SV("Feb/31"), SV("{}"), std::chrono::month_day{std::chrono::month{2}, std::chrono::day{31}});
+  check(SV("*Feb/31*"), SV("{:*^8}"), std::chrono::month_day{std::chrono::month{2}, std::chrono::day{31}});
+  check(SV("*Feb/31"), SV("{:*>7}"), std::chrono::month_day{std::chrono::month{2}, std::chrono::day{31}});
+
+  // Invalid month "valid" day
+  check(SV("0 is not a valid month/31"), SV("{}"), std::chrono::month_day{std::chrono::month{0}, std::chrono::day{31}});
+  check(SV("*0 is not a valid month/31*"),
+        SV("{:*^27}"),
+        std::chrono::month_day{std::chrono::month{0}, std::chrono::day{31}});
+
+  // Valid month invalid day
+  check(SV("Feb/32 is not a valid day"), SV("{}"), std::chrono::month_day{std::chrono::month{2}, std::chrono::day{32}});
+  check(SV("*Feb/32 is not a valid day*"),
+        SV("{:*^27}"),
+        std::chrono::month_day{std::chrono::month{2}, std::chrono::day{32}});
+  check(SV("*Feb/32 is not a valid day"),
+        SV("{:*>26}"),
+        std::chrono::month_day{std::chrono::month{2}, std::chrono::day{32}});
+
+  // Invalid month invalid day
+  check(SV("0 is not a valid month/32 is not a valid day"),
+        SV("{}"),
+        std::chrono::month_day{std::chrono::month{0}, std::chrono::day{32}});
+  check(SV("*0 is not a valid month/32 is not a valid day*"),
+        SV("{:*^46}"),
+        std::chrono::month_day{std::chrono::month{0}, std::chrono::day{32}});
+}
+
+template <class CharT>
+static void test_valid_values() {
+  // Test that %b, %h, and %B throw an exception.
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%b}"),
+                  std::chrono::month_day{std::chrono::month{200}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%b}"),
+                  std::chrono::month_day{std::chrono::month{13}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%b}"),
+                  std::chrono::month_day{std::chrono::month{255}, std::chrono::day{31}});
+
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%h}"),
+                  std::chrono::month_day{std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%h}"),
+                  std::chrono::month_day{std::chrono::month{13}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%h}"),
+                  std::chrono::month_day{std::chrono::month{255}, std::chrono::day{31}});
+
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%B}"),
+                  std::chrono::month_day{std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%B}"),
+                  std::chrono::month_day{std::chrono::month{13}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%B}"),
+                  std::chrono::month_day{std::chrono::month{255}, std::chrono::day{31}});
+
+  constexpr std::basic_string_view<CharT> fmt =
+      SV("{:%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%t%%d='%d'%t%%e='%e'%t%%Od='%Od'%t%%Oe='%Oe'%n}");
+  constexpr std::basic_string_view<CharT> lfmt =
+      SV("{:L%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%t%%d='%d'%t%%e='%e'%t%%Od='%Od'%t%%Oe='%Oe'%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(SV("%b='Jan'\t%B='January'\t%h='Jan'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::January, std::chrono::day{0}});
+  check(SV("%b='Feb'\t%B='February'\t%h='Feb'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::February, std::chrono::day{1}});
+  check(SV("%b='Mar'\t%B='March'\t%h='Mar'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='09'\t%Oe=' 9'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::March, std::chrono::day{9}});
+  check(SV("%b='Apr'\t%B='April'\t%h='Apr'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::April, std::chrono::day{10}});
+  check(SV("%b='May'\t%B='May'\t%h='May'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::May, std::chrono::day{28}});
+  check(SV("%b='Jun'\t%B='June'\t%h='Jun'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='29'\t%Oe='29'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::June, std::chrono::day{29}});
+  check(SV("%b='Jul'\t%B='July'\t%h='Jul'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::July, std::chrono::day{30}});
+  check(SV("%b='Aug'\t%B='August'\t%h='Aug'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::August, std::chrono::day{31}});
+  check(SV("%b='Sep'\t%B='September'\t%h='Sep'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='32'\t%Oe='32'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::September, std::chrono::day{32}});
+  check(SV("%b='Oct'\t%B='October'\t%h='Oct'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='99'\t%Oe='99'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::October, std::chrono::day{99}});
+#if defined(_AIX)
+  check(SV("%b='Nov'\t%B='November'\t%h='Nov'\t%m='11'\t%Om='11'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::November, std::chrono::day{100}});
+  check(SV("%b='Dec'\t%B='December'\t%h='Dec'\t%m='12'\t%Om='12'\t%d='55'\t%e='55'\t%Od='55'\t%Oe='55'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::December, std::chrono::day{255}});
+#else  //  defined(_AIX)
+  check(SV("%b='Nov'\t%B='November'\t%h='Nov'\t%m='11'\t%Om='11'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::November, std::chrono::day{100}});
+  check(SV("%b='Dec'\t%B='December'\t%h='Dec'\t%m='12'\t%Om='12'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        fmt,
+        std::chrono::month_day{std::chrono::December, std::chrono::day{255}});
+#endif //  defined(_AIX)
+
+  // Use the global locale (fr_FR)
+#if defined(__APPLE__)
+  check(SV("%b='jan'\t%B='janvier'\t%h='jan'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::January, std::chrono::day{0}});
+  check(SV("%b='fév'\t%B='février'\t%h='fév'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::February, std::chrono::day{1}});
+  check(SV("%b='mar'\t%B='mars'\t%h='mar'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='09'\t%Oe=' 9'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::March, std::chrono::day{9}});
+  check(SV("%b='avr'\t%B='avril'\t%h='avr'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::April, std::chrono::day{10}});
+  check(SV("%b='mai'\t%B='mai'\t%h='mai'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::May, std::chrono::day{28}});
+  check(SV("%b='jui'\t%B='juin'\t%h='jui'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='29'\t%Oe='29'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::June, std::chrono::day{29}});
+  check(SV("%b='jul'\t%B='juillet'\t%h='jul'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::July, std::chrono::day{30}});
+  check(SV("%b='aoû'\t%B='août'\t%h='aoû'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::August, std::chrono::day{31}});
+  check(SV("%b='sep'\t%B='septembre'\t%h='sep'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='32'\t%Oe='32'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::September, std::chrono::day{32}});
+  check(SV("%b='oct'\t%B='octobre'\t%h='oct'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='99'\t%Oe='99'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::October, std::chrono::day{99}});
+  check(SV("%b='nov'\t%B='novembre'\t%h='nov'\t%m='11'\t%Om='11'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::November, std::chrono::day{100}});
+  check(SV("%b='déc'\t%B='décembre'\t%h='déc'\t%m='12'\t%Om='12'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::December, std::chrono::day{255}});
+#else    // defined(__APPLE__)
+  check(SV("%b='janv.'\t%B='janvier'\t%h='janv.'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::January, std::chrono::day{0}});
+  check(SV("%b='févr.'\t%B='février'\t%h='févr.'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::February, std::chrono::day{1}});
+  check(SV("%b='mars'\t%B='mars'\t%h='mars'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='09'\t%Oe=' 9'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::March, std::chrono::day{9}});
+  check(
+#  if defined(_WIN32) || defined(_AIX)
+      SV("%b='avr.'\t%B='avril'\t%h='avr.'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+#  else  // defined(_WIN32) || defined(_AIX)
+      SV("%b='avril'\t%B='avril'\t%h='avril'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+#  endif // defined(_WIN32) || defined(_AIX)
+      lfmt,
+      std::chrono::month_day{std::chrono::April, std::chrono::day{10}});
+  check(SV("%b='mai'\t%B='mai'\t%h='mai'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::May, std::chrono::day{28}});
+  check(SV("%b='juin'\t%B='juin'\t%h='juin'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='29'\t%Oe='29'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::June, std::chrono::day{29}});
+  check(SV("%b='juil.'\t%B='juillet'\t%h='juil.'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::July, std::chrono::day{30}});
+  check(SV("%b='août'\t%B='août'\t%h='août'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::August, std::chrono::day{31}});
+  check(SV("%b='sept.'\t%B='septembre'\t%h='sept.'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='32'\t%Oe='32'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::September, std::chrono::day{32}});
+  check(SV("%b='oct.'\t%B='octobre'\t%h='oct.'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='99'\t%Oe='99'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::October, std::chrono::day{99}});
+#  if defined(_AIX)
+  check(SV("%b='nov.'\t%B='novembre'\t%h='nov.'\t%m='11'\t%Om='11'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::November, std::chrono::day{100}});
+  check(SV("%b='déc.'\t%B='décembre'\t%h='déc.'\t%m='12'\t%Om='12'\t%d='55'\t%e='55'\t%Od='55'\t%Oe='55'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::December, std::chrono::day{255}});
+#  else  //   defined(_AIX)
+  check(SV("%b='nov.'\t%B='novembre'\t%h='nov.'\t%m='11'\t%Om='11'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::November, std::chrono::day{100}});
+  check(SV("%b='déc.'\t%B='décembre'\t%h='déc.'\t%m='12'\t%Om='12'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::December, std::chrono::day{255}});
+#  endif //   defined(_AIX)
+#endif   // defined(__APPLE__)
+
+  // Use supplied locale (ja_JP)
+#if defined(_WIN32)
+  check(loc,
+        SV("%b='1'\t%B='1月'\t%h='1'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='〇'\t%Oe='〇'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::January, std::chrono::day{0}});
+  check(loc,
+        SV("%b='2'\t%B='2月'\t%h='2'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='一'\t%Oe='一'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::February, std::chrono::day{1}});
+  check(loc,
+        SV("%b='3'\t%B='3月'\t%h='3'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='九'\t%Oe='九'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::March, std::chrono::day{9}});
+  check(loc,
+        SV("%b='4'\t%B='4月'\t%h='4'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='十'\t%Oe='十'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::April, std::chrono::day{10}});
+  check(loc,
+        SV("%b='5'\t%B='5月'\t%h='5'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='二十八'\t%Oe='二十八'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::May, std::chrono::day{28}});
+  check(loc,
+        SV("%b='6'\t%B='6月'\t%h='6'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='二十九'\t%Oe='二十九'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::June, std::chrono::day{29}});
+  check(loc,
+        SV("%b='7'\t%B='7月'\t%h='7'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='三十'\t%Oe='三十'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::July, std::chrono::day{30}});
+  check(loc,
+        SV("%b='8'\t%B='8月'\t%h='8'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='三十一'\t%Oe='三十一'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::August, std::chrono::day{31}});
+  check(loc,
+        SV("%b='9'\t%B='9月'\t%h='9'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='三十二'\t%Oe='三十二'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::September, std::chrono::day{32}});
+  check(loc,
+        SV("%b='10'\t%B='10月'\t%h='10'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='九十九'\t%Oe='九十九'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::October, std::chrono::day{99}});
+  check(loc,
+        SV("%b='11'\t%B='11月'\t%h='11'\t%m='11'\t%Om='11'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::November, std::chrono::day{100}});
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::December, std::chrono::day{255}});
+#elif defined(_AIX)      // defined(_WIN32)
+  check(loc,
+        SV("%b='1月'\t%B='1月'\t%h='1月'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::January, std::chrono::day{0}});
+  check(loc,
+        SV("%b='2月'\t%B='2月'\t%h='2月'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::February, std::chrono::day{1}});
+  check(loc,
+        SV("%b='3月'\t%B='3月'\t%h='3月'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='09'\t%Oe=' 9'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::March, std::chrono::day{9}});
+  check(loc,
+        SV("%b='4月'\t%B='4月'\t%h='4月'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::April, std::chrono::day{10}});
+  check(loc,
+        SV("%b='5月'\t%B='5月'\t%h='5月'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::May, std::chrono::day{28}});
+  check(loc,
+        SV("%b='6月'\t%B='6月'\t%h='6月'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='29'\t%Oe='29'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::June, std::chrono::day{29}});
+  check(loc,
+        SV("%b='7月'\t%B='7月'\t%h='7月'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::July, std::chrono::day{30}});
+  check(loc,
+        SV("%b='8月'\t%B='8月'\t%h='8月'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::August, std::chrono::day{31}});
+  check(loc,
+        SV("%b='9月'\t%B='9月'\t%h='9月'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='32'\t%Oe='32'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::September, std::chrono::day{32}});
+  check(loc,
+        SV("%b='10月'\t%B='10月'\t%h='10月'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='99'\t%Oe='99'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::October, std::chrono::day{99}});
+  check(loc,
+        SV("%b='11月'\t%B='11月'\t%h='11月'\t%m='11'\t%Om='11'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::November, std::chrono::day{100}});
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='12'\t%d='55'\t%e='55'\t%Od='55'\t%Oe='55'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::December, std::chrono::day{255}});
+#elif defined(__APPLE__) // defined(_WIN32)
+  check(loc,
+        SV("%b=' 1'\t%B='1月'\t%h=' 1'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::January, std::chrono::day{0}});
+  check(loc,
+        SV("%b=' 2'\t%B='2月'\t%h=' 2'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::February, std::chrono::day{1}});
+  check(loc,
+        SV("%b=' 3'\t%B='3月'\t%h=' 3'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='09'\t%Oe=' 9'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::March, std::chrono::day{9}});
+  check(loc,
+        SV("%b=' 4'\t%B='4月'\t%h=' 4'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::April, std::chrono::day{10}});
+  check(loc,
+        SV("%b=' 5'\t%B='5月'\t%h=' 5'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::May, std::chrono::day{28}});
+  check(loc,
+        SV("%b=' 6'\t%B='6月'\t%h=' 6'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='29'\t%Oe='29'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::June, std::chrono::day{29}});
+  check(loc,
+        SV("%b=' 7'\t%B='7月'\t%h=' 7'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::July, std::chrono::day{30}});
+  check(loc,
+        SV("%b=' 8'\t%B='8月'\t%h=' 8'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::August, std::chrono::day{31}});
+  check(loc,
+        SV("%b=' 9'\t%B='9月'\t%h=' 9'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='32'\t%Oe='32'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::September, std::chrono::day{32}});
+  check(loc,
+        SV("%b='10'\t%B='10月'\t%h='10'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='99'\t%Oe='99'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::October, std::chrono::day{99}});
+  check(loc,
+        SV("%b='11'\t%B='11月'\t%h='11'\t%m='11'\t%Om='11'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::November, std::chrono::day{100}});
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::December, std::chrono::day{255}});
+#else                    // defined(_WIN32)
+  check(loc,
+        SV("%b=' 1月'\t%B='1月'\t%h=' 1月'\t%m='01'\t%Om='一'\t%d='00'\t%e=' 0'\t%Od='〇'\t%Oe='〇'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::January, std::chrono::day{0}});
+  check(loc,
+        SV("%b=' 2月'\t%B='2月'\t%h=' 2月'\t%m='02'\t%Om='二'\t%d='01'\t%e=' 1'\t%Od='一'\t%Oe='一'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::February, std::chrono::day{1}});
+  check(loc,
+        SV("%b=' 3月'\t%B='3月'\t%h=' 3月'\t%m='03'\t%Om='三'\t%d='09'\t%e=' 9'\t%Od='九'\t%Oe='九'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::March, std::chrono::day{9}});
+  check(loc,
+        SV("%b=' 4月'\t%B='4月'\t%h=' 4月'\t%m='04'\t%Om='四'\t%d='10'\t%e='10'\t%Od='十'\t%Oe='十'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::April, std::chrono::day{10}});
+  check(loc,
+        SV("%b=' 5月'\t%B='5月'\t%h=' 5月'\t%m='05'\t%Om='五'\t%d='28'\t%e='28'\t%Od='二十八'\t%Oe='二十八'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::May, std::chrono::day{28}});
+  check(loc,
+        SV("%b=' 6月'\t%B='6月'\t%h=' 6月'\t%m='06'\t%Om='六'\t%d='29'\t%e='29'\t%Od='二十九'\t%Oe='二十九'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::June, std::chrono::day{29}});
+  check(loc,
+        SV("%b=' 7月'\t%B='7月'\t%h=' 7月'\t%m='07'\t%Om='七'\t%d='30'\t%e='30'\t%Od='三十'\t%Oe='三十'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::July, std::chrono::day{30}});
+  check(loc,
+        SV("%b=' 8月'\t%B='8月'\t%h=' 8月'\t%m='08'\t%Om='八'\t%d='31'\t%e='31'\t%Od='三十一'\t%Oe='三十一'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::August, std::chrono::day{31}});
+  check(loc,
+        SV("%b=' 9月'\t%B='9月'\t%h=' 9月'\t%m='09'\t%Om='九'\t%d='32'\t%e='32'\t%Od='三十二'\t%Oe='三十二'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::September, std::chrono::day{32}});
+  check(loc,
+        SV("%b='10月'\t%B='10月'\t%h='10月'\t%m='10'\t%Om='十'\t%d='99'\t%e='99'\t%Od='九十九'\t%Oe='九十九'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::October, std::chrono::day{99}});
+  check(loc,
+        SV("%b='11月'\t%B='11月'\t%h='11月'\t%m='11'\t%Om='十一'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::November, std::chrono::day{100}});
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='十二'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        lfmt,
+        std::chrono::month_day{std::chrono::December, std::chrono::day{255}});
+#endif                   //  defined(_WIN32)
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test() {
+  test_no_chrono_specs<CharT>();
+  test_valid_values<CharT>();
+  check_invalid_types<CharT>({SV("b"), SV("B"), SV("d"), SV("e"), SV("h"), SV("m"), SV("Od"), SV("Oe"), SV("Om")},
+                             std::chrono::month_day{std::chrono::January, std::chrono::day{31}});
+
+  check_exception("Expected '%' or '}' in the chrono format-string",
+                  SV("{:A"),
+                  std::chrono::month_day{std::chrono::January, std::chrono::day{31}});
+  check_exception("The chrono-specs contains a '{'",
+                  SV("{:%%{"),
+                  std::chrono::month_day{std::chrono::January, std::chrono::day{31}});
+  check_exception("End of input while parsing the modifier chrono conversion-spec",
+                  SV("{:%"),
+                  std::chrono::month_day{std::chrono::January, std::chrono::day{31}});
+  check_exception("End of input while parsing the modifier E",
+                  SV("{:%E"),
+                  std::chrono::month_day{std::chrono::January, std::chrono::day{31}});
+  check_exception("End of input while parsing the modifier O",
+                  SV("{:%O"),
+                  std::chrono::month_day{std::chrono::January, std::chrono::day{31}});
+
+  // Precision not allowed
+  check_exception("Expected '%' or '}' in the chrono format-string",
+                  SV("{:.3}"),
+                  std::chrono::month_day{std::chrono::January, std::chrono::day{31}});
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.syn/formatter.month_day_last.pass.cpp b/libcxx/test/std/time/time.syn/formatter.month_day_last.pass.cpp
new file mode 100644
index 0000000000000..d7f3fc6fa2b10
--- /dev/null
+++ b/libcxx/test/std/time/time.syn/formatter.month_day_last.pass.cpp
@@ -0,0 +1,403 @@
+//===----------------------------------------------------------------------===//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// template<class charT> struct formatter<chrono::month_day_last, charT>;
+
+#include <chrono>
+#include <format>
+
+#include <cassert>
+#include <concepts>
+#include <locale>
+#include <iostream>
+#include <type_traits>
+
+#include "formatter_tests.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "string_literal.h"
+#include "test_macros.h"
+
+template <class CharT>
+static void test_no_chrono_specs() {
+  // Valid month
+  check(SV("Jan/last"), SV("{}"), std::chrono::month_day_last{std::chrono::month{1}});
+  check(SV("*Jan/last*"), SV("{:*^10}"), std::chrono::month_day_last{std::chrono::month{1}});
+  check(SV("*Jan/last"), SV("{:*>9}"), std::chrono::month_day_last{std::chrono::month{1}});
+
+  // Invalid month
+  check(SV("0 is not a valid month/last"), SV("{}"), std::chrono::month_day_last{std::chrono::month{0}});
+  check(SV("*0 is not a valid month/last*"), SV("{:*^29}"), std::chrono::month_day_last{std::chrono::month{0}});
+}
+
+template <class CharT>
+static void test_valid_values() {
+  // Test that %b, %h, and %B throw an exception.
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%b}"),
+                  std::chrono::month_day_last{std::chrono::month{200}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%b}"),
+                  std::chrono::month_day_last{std::chrono::month{13}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%b}"),
+                  std::chrono::month_day_last{std::chrono::month{255}});
+
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%h}"),
+                  std::chrono::month_day_last{std::chrono::month{0}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%h}"),
+                  std::chrono::month_day_last{std::chrono::month{13}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%h}"),
+                  std::chrono::month_day_last{std::chrono::month{255}});
+
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%B}"),
+                  std::chrono::month_day_last{std::chrono::month{0}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%B}"),
+                  std::chrono::month_day_last{std::chrono::month{13}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%B}"),
+                  std::chrono::month_day_last{std::chrono::month{255}});
+
+  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%n}");
+  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(SV("%b='Jan'\t%B='January'\t%h='Jan'\t%m='01'\t%Om='01'\n"),
+        fmt,
+        std::chrono::month_day_last{std::chrono::January});
+  check(SV("%b='Feb'\t%B='February'\t%h='Feb'\t%m='02'\t%Om='02'\n"),
+        fmt,
+        std::chrono::month_day_last{std::chrono::February});
+  check(
+      SV("%b='Mar'\t%B='March'\t%h='Mar'\t%m='03'\t%Om='03'\n"), fmt, std::chrono::month_day_last{std::chrono::March});
+  check(
+      SV("%b='Apr'\t%B='April'\t%h='Apr'\t%m='04'\t%Om='04'\n"), fmt, std::chrono::month_day_last{std::chrono::April});
+  check(SV("%b='May'\t%B='May'\t%h='May'\t%m='05'\t%Om='05'\n"), fmt, std::chrono::month_day_last{std::chrono::May});
+  check(SV("%b='Jun'\t%B='June'\t%h='Jun'\t%m='06'\t%Om='06'\n"), fmt, std::chrono::month_day_last{std::chrono::June});
+  check(SV("%b='Jul'\t%B='July'\t%h='Jul'\t%m='07'\t%Om='07'\n"), fmt, std::chrono::month_day_last{std::chrono::July});
+  check(SV("%b='Aug'\t%B='August'\t%h='Aug'\t%m='08'\t%Om='08'\n"),
+        fmt,
+        std::chrono::month_day_last{std::chrono::August});
+  check(SV("%b='Sep'\t%B='September'\t%h='Sep'\t%m='09'\t%Om='09'\n"),
+        fmt,
+        std::chrono::month_day_last{std::chrono::September});
+  check(SV("%b='Oct'\t%B='October'\t%h='Oct'\t%m='10'\t%Om='10'\n"),
+        fmt,
+        std::chrono::month_day_last{std::chrono::October});
+  check(SV("%b='Nov'\t%B='November'\t%h='Nov'\t%m='11'\t%Om='11'\n"),
+        fmt,
+        std::chrono::month_day_last{std::chrono::November});
+  check(SV("%b='Dec'\t%B='December'\t%h='Dec'\t%m='12'\t%Om='12'\n"),
+        fmt,
+        std::chrono::month_day_last{std::chrono::December});
+
+  // Use the global locale (fr_FR)
+#if defined(__APPLE__)
+  check(SV("%b='jan'\t%B='janvier'\t%h='jan'\t%m='01'\t%Om='01'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::January});
+  check(SV("%b='fév'\t%B='février'\t%h='fév'\t%m='02'\t%Om='02'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::February});
+  check(
+      SV("%b='mar'\t%B='mars'\t%h='mar'\t%m='03'\t%Om='03'\n"), lfmt, std::chrono::month_day_last{std::chrono::March});
+  check(
+      SV("%b='avr'\t%B='avril'\t%h='avr'\t%m='04'\t%Om='04'\n"), lfmt, std::chrono::month_day_last{std::chrono::April});
+  check(SV("%b='mai'\t%B='mai'\t%h='mai'\t%m='05'\t%Om='05'\n"), lfmt, std::chrono::month_day_last{std::chrono::May});
+  check(SV("%b='jui'\t%B='juin'\t%h='jui'\t%m='06'\t%Om='06'\n"), lfmt, std::chrono::month_day_last{std::chrono::June});
+  check(SV("%b='jul'\t%B='juillet'\t%h='jul'\t%m='07'\t%Om='07'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::July});
+  check(
+      SV("%b='aoû'\t%B='août'\t%h='aoû'\t%m='08'\t%Om='08'\n"), lfmt, std::chrono::month_day_last{std::chrono::August});
+  check(SV("%b='sep'\t%B='septembre'\t%h='sep'\t%m='09'\t%Om='09'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::September});
+  check(SV("%b='oct'\t%B='octobre'\t%h='oct'\t%m='10'\t%Om='10'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::October});
+  check(SV("%b='nov'\t%B='novembre'\t%h='nov'\t%m='11'\t%Om='11'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::November});
+  check(SV("%b='déc'\t%B='décembre'\t%h='déc'\t%m='12'\t%Om='12'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::December});
+#else    // defined(__APPLE__)
+  check(SV("%b='janv.'\t%B='janvier'\t%h='janv.'\t%m='01'\t%Om='01'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::January});
+  check(SV("%b='févr.'\t%B='février'\t%h='févr.'\t%m='02'\t%Om='02'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::February});
+  check(SV("%b='mars'\t%B='mars'\t%h='mars'\t%m='03'\t%Om='03'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::March});
+  check(
+#  if defined(_WIN32) || defined(_AIX)
+      SV("%b='avr.'\t%B='avril'\t%h='avr.'\t%m='04'\t%Om='04'\n"),
+#  else  // defined(_WIN32) || defined(_AIX)
+      SV("%b='avril'\t%B='avril'\t%h='avril'\t%m='04'\t%Om='04'\n"),
+#  endif // defined(_WIN32) || defined(_AIX)
+      lfmt,
+      std::chrono::month_day_last{std::chrono::April});
+  check(SV("%b='mai'\t%B='mai'\t%h='mai'\t%m='05'\t%Om='05'\n"), lfmt, std::chrono::month_day_last{std::chrono::May});
+  check(
+      SV("%b='juin'\t%B='juin'\t%h='juin'\t%m='06'\t%Om='06'\n"), lfmt, std::chrono::month_day_last{std::chrono::June});
+  check(SV("%b='juil.'\t%B='juillet'\t%h='juil.'\t%m='07'\t%Om='07'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::July});
+  check(SV("%b='août'\t%B='août'\t%h='août'\t%m='08'\t%Om='08'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::August});
+  check(SV("%b='sept.'\t%B='septembre'\t%h='sept.'\t%m='09'\t%Om='09'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::September});
+  check(SV("%b='oct.'\t%B='octobre'\t%h='oct.'\t%m='10'\t%Om='10'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::October});
+  check(SV("%b='nov.'\t%B='novembre'\t%h='nov.'\t%m='11'\t%Om='11'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::November});
+  check(SV("%b='déc.'\t%B='décembre'\t%h='déc.'\t%m='12'\t%Om='12'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::December});
+#endif   // defined(__APPLE__)
+
+  // Use supplied locale (ja_JP)
+#ifdef _WIN32
+  check(loc,
+        SV("%b='1'\t%B='1月'\t%h='1'\t%m='01'\t%Om='01'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::January});
+  check(loc,
+        SV("%b='2'\t%B='2月'\t%h='2'\t%m='02'\t%Om='02'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::February});
+  check(
+      loc, SV("%b='3'\t%B='3月'\t%h='3'\t%m='03'\t%Om='03'\n"), lfmt, std::chrono::month_day_last{std::chrono::March});
+  check(
+      loc, SV("%b='4'\t%B='4月'\t%h='4'\t%m='04'\t%Om='04'\n"), lfmt, std::chrono::month_day_last{std::chrono::April});
+  check(loc, SV("%b='5'\t%B='5月'\t%h='5'\t%m='05'\t%Om='05'\n"), lfmt, std::chrono::month_day_last{std::chrono::May});
+  check(loc, SV("%b='6'\t%B='6月'\t%h='6'\t%m='06'\t%Om='06'\n"), lfmt, std::chrono::month_day_last{std::chrono::June});
+  check(loc, SV("%b='7'\t%B='7月'\t%h='7'\t%m='07'\t%Om='07'\n"), lfmt, std::chrono::month_day_last{std::chrono::July});
+  check(
+      loc, SV("%b='8'\t%B='8月'\t%h='8'\t%m='08'\t%Om='08'\n"), lfmt, std::chrono::month_day_last{std::chrono::August});
+  check(loc,
+        SV("%b='9'\t%B='9月'\t%h='9'\t%m='09'\t%Om='09'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::September});
+  check(loc,
+        SV("%b='10'\t%B='10月'\t%h='10'\t%m='10'\t%Om='10'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::October});
+  check(loc,
+        SV("%b='11'\t%B='11月'\t%h='11'\t%m='11'\t%Om='11'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::November});
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::December});
+#elif defined(__APPLE__) // defined(_WIN32)
+  check(loc,
+        SV("%b=' 1'\t%B='1月'\t%h=' 1'\t%m='01'\t%Om='01'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::January});
+  check(loc,
+        SV("%b=' 2'\t%B='2月'\t%h=' 2'\t%m='02'\t%Om='02'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::February});
+  check(loc,
+        SV("%b=' 3'\t%B='3月'\t%h=' 3'\t%m='03'\t%Om='03'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::March});
+  check(loc,
+        SV("%b=' 4'\t%B='4月'\t%h=' 4'\t%m='04'\t%Om='04'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::April});
+  check(
+      loc, SV("%b=' 5'\t%B='5月'\t%h=' 5'\t%m='05'\t%Om='05'\n"), lfmt, std::chrono::month_day_last{std::chrono::May});
+  check(
+      loc, SV("%b=' 6'\t%B='6月'\t%h=' 6'\t%m='06'\t%Om='06'\n"), lfmt, std::chrono::month_day_last{std::chrono::June});
+  check(
+      loc, SV("%b=' 7'\t%B='7月'\t%h=' 7'\t%m='07'\t%Om='07'\n"), lfmt, std::chrono::month_day_last{std::chrono::July});
+  check(loc,
+        SV("%b=' 8'\t%B='8月'\t%h=' 8'\t%m='08'\t%Om='08'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::August});
+  check(loc,
+        SV("%b=' 9'\t%B='9月'\t%h=' 9'\t%m='09'\t%Om='09'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::September});
+  check(loc,
+        SV("%b='10'\t%B='10月'\t%h='10'\t%m='10'\t%Om='10'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::October});
+  check(loc,
+        SV("%b='11'\t%B='11月'\t%h='11'\t%m='11'\t%Om='11'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::November});
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::December});
+#elif defined(_AIX)      // defined(_WIN32)
+  check(loc,
+        SV("%b='1月'\t%B='1月'\t%h='1月'\t%m='01'\t%Om='01'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::January});
+  check(loc,
+        SV("%b='2月'\t%B='2月'\t%h='2月'\t%m='02'\t%Om='02'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::February});
+  check(loc,
+        SV("%b='3月'\t%B='3月'\t%h='3月'\t%m='03'\t%Om='03'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::March});
+  check(loc,
+        SV("%b='4月'\t%B='4月'\t%h='4月'\t%m='04'\t%Om='04'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::April});
+  check(loc,
+        SV("%b='5月'\t%B='5月'\t%h='5月'\t%m='05'\t%Om='05'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::May});
+  check(loc,
+        SV("%b='6月'\t%B='6月'\t%h='6月'\t%m='06'\t%Om='06'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::June});
+  check(loc,
+        SV("%b='7月'\t%B='7月'\t%h='7月'\t%m='07'\t%Om='07'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::July});
+  check(loc,
+        SV("%b='8月'\t%B='8月'\t%h='8月'\t%m='08'\t%Om='08'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::August});
+  check(loc,
+        SV("%b='9月'\t%B='9月'\t%h='9月'\t%m='09'\t%Om='09'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::September});
+  check(loc,
+        SV("%b='10月'\t%B='10月'\t%h='10月'\t%m='10'\t%Om='10'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::October});
+  check(loc,
+        SV("%b='11月'\t%B='11月'\t%h='11月'\t%m='11'\t%Om='11'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::November});
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='12'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::December});
+#else                    // defined(_WIN32)
+  check(loc,
+        SV("%b=' 1月'\t%B='1月'\t%h=' 1月'\t%m='01'\t%Om='一'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::January});
+  check(loc,
+        SV("%b=' 2月'\t%B='2月'\t%h=' 2月'\t%m='02'\t%Om='二'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::February});
+  check(loc,
+        SV("%b=' 3月'\t%B='3月'\t%h=' 3月'\t%m='03'\t%Om='三'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::March});
+  check(loc,
+        SV("%b=' 4月'\t%B='4月'\t%h=' 4月'\t%m='04'\t%Om='四'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::April});
+  check(loc,
+        SV("%b=' 5月'\t%B='5月'\t%h=' 5月'\t%m='05'\t%Om='五'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::May});
+  check(loc,
+        SV("%b=' 6月'\t%B='6月'\t%h=' 6月'\t%m='06'\t%Om='六'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::June});
+  check(loc,
+        SV("%b=' 7月'\t%B='7月'\t%h=' 7月'\t%m='07'\t%Om='七'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::July});
+  check(loc,
+        SV("%b=' 8月'\t%B='8月'\t%h=' 8月'\t%m='08'\t%Om='八'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::August});
+  check(loc,
+        SV("%b=' 9月'\t%B='9月'\t%h=' 9月'\t%m='09'\t%Om='九'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::September});
+  check(loc,
+        SV("%b='10月'\t%B='10月'\t%h='10月'\t%m='10'\t%Om='十'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::October});
+  check(loc,
+        SV("%b='11月'\t%B='11月'\t%h='11月'\t%m='11'\t%Om='十一'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::November});
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='十二'\n"),
+        lfmt,
+        std::chrono::month_day_last{std::chrono::December});
+#endif                   // defined(_WIN32)
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test() {
+  test_no_chrono_specs<CharT>();
+  test_valid_values<CharT>();
+  check_invalid_types<CharT>(
+      {SV("b"), SV("B"), SV("h"), SV("m"), SV("Om")}, std::chrono::month_day_last{std::chrono::January});
+
+  check_exception(
+      "Expected '%' or '}' in the chrono format-string", SV("{:A"), std::chrono::month_day_last{std::chrono::January});
+  check_exception("The chrono-specs contains a '{'", SV("{:%%{"), std::chrono::month_day_last{std::chrono::January});
+  check_exception("End of input while parsing the modifier chrono conversion-spec",
+                  SV("{:%"),
+                  std::chrono::month_day_last{std::chrono::January});
+  check_exception(
+      "End of input while parsing the modifier E", SV("{:%E"), std::chrono::month_day_last{std::chrono::January});
+  check_exception(
+      "End of input while parsing the modifier O", SV("{:%O"), std::chrono::month_day_last{std::chrono::January});
+
+  // Precision not allowed
+  check_exception("Expected '%' or '}' in the chrono format-string",
+                  SV("{:.3}"),
+                  std::chrono::month_day_last{std::chrono::January});
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.syn/formatter.month_weekday.pass.cpp b/libcxx/test/std/time/time.syn/formatter.month_weekday.pass.cpp
new file mode 100644
index 0000000000000..3c6a7b9d9f1c5
--- /dev/null
+++ b/libcxx/test/std/time/time.syn/formatter.month_weekday.pass.cpp
@@ -0,0 +1,721 @@
+//===----------------------------------------------------------------------===//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// template<class charT> struct formatter<chrono::month_weekday, charT>;
+
+#include <chrono>
+#include <format>
+
+#include <cassert>
+#include <concepts>
+#include <locale>
+#include <iostream>
+#include <type_traits>
+
+#include "formatter_tests.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "string_literal.h"
+#include "test_macros.h"
+
+template <class CharT>
+static void test_no_chrono_specs() {
+  // Month: valid,   weekday: valid,   index: invalid
+  check(SV("Jan/Sun[0 is not a valid index]"),
+        SV("{}"),
+        std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 0}});
+  check(SV("*Jan/Sun[0 is not a valid index]*"),
+        SV("{:*^33}"),
+        std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 0}});
+  check(SV("*Jan/Sun[0 is not a valid index]"),
+        SV("{:*>32}"),
+        std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 0}});
+
+  // Month: valid,   weekday: invalid, index: valid
+  check(SV("Jan/8 is not a valid weekday[1]"),
+        SV("{}"),
+        std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 1}});
+  check(SV("*Jan/8 is not a valid weekday[1]*"),
+        SV("{:*^33}"),
+        std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 1}});
+  check(SV("*Jan/8 is not a valid weekday[1]"),
+        SV("{:*>32}"),
+        std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 1}});
+
+  // Month: valid,   weekday: invalid,   index: invalid
+  check(SV("Jan/8 is not a valid weekday[0 is not a valid index]"),
+        SV("{}"),
+        std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}});
+  check(SV("*Jan/8 is not a valid weekday[0 is not a valid index]*"),
+        SV("{:*^54}"),
+        std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}});
+  check(SV("*Jan/8 is not a valid weekday[0 is not a valid index]"),
+        SV("{:*>53}"),
+        std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}});
+
+  // Month: invalid, weekday: valid,   index: valid
+  check(SV("0 is not a valid month/Sun[1]"),
+        SV("{}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("*0 is not a valid month/Sun[1]*"),
+        SV("{:*^31}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("*0 is not a valid month/Sun[1]"),
+        SV("{:*>30}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+
+  // Month: invalid, weekday: valid,   index: invalid
+  check(SV("0 is not a valid month/Sun[0 is not a valid index]"),
+        SV("{}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 0}});
+  check(SV("*0 is not a valid month/Sun[0 is not a valid index]*"),
+        SV("{:*^52}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 0}});
+  check(SV("*0 is not a valid month/Sun[0 is not a valid index]"),
+        SV("{:*>51}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 0}});
+
+  // Month: invalid, weekday: invalid, index: valid
+  check(SV("0 is not a valid month/8 is not a valid weekday[1]"),
+        SV("{}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 1}});
+  check(SV("*0 is not a valid month/8 is not a valid weekday[1]*"),
+        SV("{:*^52}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 1}});
+  check(SV("*0 is not a valid month/8 is not a valid weekday[1]"),
+        SV("{:*>51}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 1}});
+
+  // Month: invalid, weekday: valid,   index: invalid
+  check(SV("0 is not a valid month/8 is not a valid weekday[0 is not a valid index]"),
+        SV("{}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}});
+  check(SV("*0 is not a valid month/8 is not a valid weekday[0 is not a valid index]*"),
+        SV("{:*^73}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}});
+  check(SV("*0 is not a valid month/8 is not a valid weekday[0 is not a valid index]"),
+        SV("{:*>72}"),
+        std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 0}});
+}
+
+template <class CharT>
+static void test_invalid_values() {
+  // Test that %a, %b, %h, %a, and %B throw an exception.
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%a}"),
+      std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 1}});
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%a}"),
+      std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{255}, 1}});
+
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%b}"),
+      std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%b}"),
+      std::chrono::month_weekday{std::chrono::month{13}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%b}"),
+      std::chrono::month_weekday{std::chrono::month{255}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%h}"),
+      std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%h}"),
+      std::chrono::month_weekday{std::chrono::month{13}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%h}"),
+      std::chrono::month_weekday{std::chrono::month{255}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%A}"),
+      std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{8}, 1}});
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%A}"),
+      std::chrono::month_weekday{std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{255}, 1}});
+
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%B}"),
+      std::chrono::month_weekday{std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%B}"),
+      std::chrono::month_weekday{std::chrono::month{13}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%B}"),
+      std::chrono::month_weekday{std::chrono::month{255}, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+}
+
+template <class CharT>
+static void test_valid_month() {
+  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%n}");
+  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(SV("%b='Jan'\t%B='January'\t%h='Jan'\t%m='01'\t%Om='01'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='Feb'\t%B='February'\t%h='Feb'\t%m='02'\t%Om='02'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::February, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='Mar'\t%B='March'\t%h='Mar'\t%m='03'\t%Om='03'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::March, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='Apr'\t%B='April'\t%h='Apr'\t%m='04'\t%Om='04'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::April, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='May'\t%B='May'\t%h='May'\t%m='05'\t%Om='05'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='Jun'\t%B='June'\t%h='Jun'\t%m='06'\t%Om='06'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::June, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='Jul'\t%B='July'\t%h='Jul'\t%m='07'\t%Om='07'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::July, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='Aug'\t%B='August'\t%h='Aug'\t%m='08'\t%Om='08'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::August, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='Sep'\t%B='September'\t%h='Sep'\t%m='09'\t%Om='09'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::September, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='Oct'\t%B='October'\t%h='Oct'\t%m='10'\t%Om='10'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::October, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='Nov'\t%B='November'\t%h='Nov'\t%m='11'\t%Om='11'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::November, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='Dec'\t%B='December'\t%h='Dec'\t%m='12'\t%Om='12'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+
+  // Use the global locale (fr_FR)
+#if defined(__APPLE__)
+  check(SV("%b='jan'\t%B='janvier'\t%h='jan'\t%m='01'\t%Om='01'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='fév'\t%B='février'\t%h='fév'\t%m='02'\t%Om='02'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::February, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='mar'\t%B='mars'\t%h='mar'\t%m='03'\t%Om='03'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::March, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='avr'\t%B='avril'\t%h='avr'\t%m='04'\t%Om='04'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::April, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='mai'\t%B='mai'\t%h='mai'\t%m='05'\t%Om='05'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='jui'\t%B='juin'\t%h='jui'\t%m='06'\t%Om='06'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::June, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='jul'\t%B='juillet'\t%h='jul'\t%m='07'\t%Om='07'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::July, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='aoû'\t%B='août'\t%h='aoû'\t%m='08'\t%Om='08'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::August, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='sep'\t%B='septembre'\t%h='sep'\t%m='09'\t%Om='09'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::September, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='oct'\t%B='octobre'\t%h='oct'\t%m='10'\t%Om='10'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::October, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='nov'\t%B='novembre'\t%h='nov'\t%m='11'\t%Om='11'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::November, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='déc'\t%B='décembre'\t%h='déc'\t%m='12'\t%Om='12'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+#else    // defined(__APPLE__)
+  check(SV("%b='janv.'\t%B='janvier'\t%h='janv.'\t%m='01'\t%Om='01'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='févr.'\t%B='février'\t%h='févr.'\t%m='02'\t%Om='02'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::February, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='mars'\t%B='mars'\t%h='mars'\t%m='03'\t%Om='03'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::March, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(
+#  if defined(_WIN32) || defined(_AIX)
+      SV("%b='avr.'\t%B='avril'\t%h='avr.'\t%m='04'\t%Om='04'\n"),
+#  else  // defined(_WIN32) || defined(_AIX)
+      SV("%b='avril'\t%B='avril'\t%h='avril'\t%m='04'\t%Om='04'\n"),
+#  endif // defined(_WIN32) || defined(_AIX)
+      lfmt,
+      std::chrono::month_weekday{std::chrono::April, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='mai'\t%B='mai'\t%h='mai'\t%m='05'\t%Om='05'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='juin'\t%B='juin'\t%h='juin'\t%m='06'\t%Om='06'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::June, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='juil.'\t%B='juillet'\t%h='juil.'\t%m='07'\t%Om='07'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::July, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='août'\t%B='août'\t%h='août'\t%m='08'\t%Om='08'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::August, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='sept.'\t%B='septembre'\t%h='sept.'\t%m='09'\t%Om='09'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::September, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='oct.'\t%B='octobre'\t%h='oct.'\t%m='10'\t%Om='10'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::October, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='nov.'\t%B='novembre'\t%h='nov.'\t%m='11'\t%Om='11'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::November, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%b='déc.'\t%B='décembre'\t%h='déc.'\t%m='12'\t%Om='12'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+#endif   // defined(__APPLE__)
+
+  // Use supplied locale (ja_JP)
+#ifdef _WIN32
+  check(loc,
+        SV("%b='1'\t%B='1月'\t%h='1'\t%m='01'\t%Om='01'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='2'\t%B='2月'\t%h='2'\t%m='02'\t%Om='02'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::February, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='3'\t%B='3月'\t%h='3'\t%m='03'\t%Om='03'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::March, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='4'\t%B='4月'\t%h='4'\t%m='04'\t%Om='04'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::April, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='5'\t%B='5月'\t%h='5'\t%m='05'\t%Om='05'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='6'\t%B='6月'\t%h='6'\t%m='06'\t%Om='06'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::June, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='7'\t%B='7月'\t%h='7'\t%m='07'\t%Om='07'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::July, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='8'\t%B='8月'\t%h='8'\t%m='08'\t%Om='08'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::August, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='9'\t%B='9月'\t%h='9'\t%m='09'\t%Om='09'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::September, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='10'\t%B='10月'\t%h='10'\t%m='10'\t%Om='10'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::October, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='11'\t%B='11月'\t%h='11'\t%m='11'\t%Om='11'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::November, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+#elif defined(__APPLE__) // defined(_WIN32)
+  check(loc,
+        SV("%b=' 1'\t%B='1月'\t%h=' 1'\t%m='01'\t%Om='01'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 2'\t%B='2月'\t%h=' 2'\t%m='02'\t%Om='02'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::February, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 3'\t%B='3月'\t%h=' 3'\t%m='03'\t%Om='03'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::March, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 4'\t%B='4月'\t%h=' 4'\t%m='04'\t%Om='04'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::April, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 5'\t%B='5月'\t%h=' 5'\t%m='05'\t%Om='05'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 6'\t%B='6月'\t%h=' 6'\t%m='06'\t%Om='06'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::June, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 7'\t%B='7月'\t%h=' 7'\t%m='07'\t%Om='07'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::July, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 8'\t%B='8月'\t%h=' 8'\t%m='08'\t%Om='08'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::August, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 9'\t%B='9月'\t%h=' 9'\t%m='09'\t%Om='09'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::September, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='10'\t%B='10月'\t%h='10'\t%m='10'\t%Om='10'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::October, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='11'\t%B='11月'\t%h='11'\t%m='11'\t%Om='11'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::November, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+#elif defined(_AIX)      // _WIN32
+  check(loc,
+        SV("%b='1月'\t%B='1月'\t%h='1月'\t%m='01'\t%Om='01'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='2月'\t%B='2月'\t%h='2月'\t%m='02'\t%Om='02'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::February, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='3月'\t%B='3月'\t%h='3月'\t%m='03'\t%Om='03'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::March, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='4月'\t%B='4月'\t%h='4月'\t%m='04'\t%Om='04'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::April, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='5月'\t%B='5月'\t%h='5月'\t%m='05'\t%Om='05'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='6月'\t%B='6月'\t%h='6月'\t%m='06'\t%Om='06'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::June, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='7月'\t%B='7月'\t%h='7月'\t%m='07'\t%Om='07'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::July, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='8月'\t%B='8月'\t%h='8月'\t%m='08'\t%Om='08'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::August, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='9月'\t%B='9月'\t%h='9月'\t%m='09'\t%Om='09'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::September, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='10月'\t%B='10月'\t%h='10月'\t%m='10'\t%Om='10'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::October, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='11月'\t%B='11月'\t%h='11月'\t%m='11'\t%Om='11'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::November, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='12'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+#else                    // _WIN32
+  check(loc,
+        SV("%b=' 1月'\t%B='1月'\t%h=' 1月'\t%m='01'\t%Om='一'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 2月'\t%B='2月'\t%h=' 2月'\t%m='02'\t%Om='二'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::February, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 3月'\t%B='3月'\t%h=' 3月'\t%m='03'\t%Om='三'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::March, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 4月'\t%B='4月'\t%h=' 4月'\t%m='04'\t%Om='四'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::April, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 5月'\t%B='5月'\t%h=' 5月'\t%m='05'\t%Om='五'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 6月'\t%B='6月'\t%h=' 6月'\t%m='06'\t%Om='六'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::June, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 7月'\t%B='7月'\t%h=' 7月'\t%m='07'\t%Om='七'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::July, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 8月'\t%B='8月'\t%h=' 8月'\t%m='08'\t%Om='八'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::August, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b=' 9月'\t%B='9月'\t%h=' 9月'\t%m='09'\t%Om='九'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::September, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='10月'\t%B='10月'\t%h='10月'\t%m='10'\t%Om='十'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::October, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='11月'\t%B='11月'\t%h='11月'\t%m='11'\t%Om='十一'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::November, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='十二'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+#endif                   // _WIN32
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test_valid_weekday() {
+  constexpr std::basic_string_view<CharT> fmt =
+      SV("{:%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}");
+  constexpr std::basic_string_view<CharT> lfmt =
+      SV("{:L%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Mon'\t%A='Monday'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Tue'\t%A='Tuesday'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{2}, 1}});
+  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Wed'\t%A='Wednesday'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{3}, 1}});
+  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Thu'\t%A='Thursday'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Fri'\t%A='Friday'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{5}, 1}});
+  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sat'\t%A='Saturday'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{6}, 1}});
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"),
+        fmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{7}, 1}});
+
+  // Use the global locale (fr_FR)
+#if defined(__APPLE__)
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Lun'\t%A='Lundi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Mar'\t%A='Mardi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{2}, 1}});
+  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Mer'\t%A='Mercredi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{3}, 1}});
+  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Jeu'\t%A='Jeudi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Ven'\t%A='Vendredi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{5}, 1}});
+  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sam'\t%A='Samedi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{6}, 1}});
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{7}, 1}});
+#else  // defined(__APPLE__)
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='lun.'\t%A='lundi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='mar.'\t%A='mardi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{2}, 1}});
+  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='mer.'\t%A='mercredi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{3}, 1}});
+  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='jeu.'\t%A='jeudi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='ven.'\t%A='vendredi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{5}, 1}});
+  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='sam.'\t%A='samedi'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{6}, 1}});
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{7}, 1}});
+#endif // defined(__APPLE__)
+
+  // Use supplied locale (ja_JP).
+  // This locale has a 
diff erent alternate, but not on all platforms
+#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX)
+  check(loc,
+        SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='月'\t%A='月曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check(loc,
+        SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='火'\t%A='火曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{2}, 1}});
+  check(loc,
+        SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='水'\t%A='水曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{3}, 1}});
+  check(loc,
+        SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='木'\t%A='木曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+  check(loc,
+        SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='金'\t%A='金曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{5}, 1}});
+  check(loc,
+        SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='土'\t%A='土曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{6}, 1}});
+  check(loc,
+        SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{7}, 1}});
+#else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)
+  check(loc,
+        SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check(loc,
+        SV("%u='1'\t%Ou='一'\t%w='1'\t%Ow='一'\t%a='月'\t%A='月曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check(loc,
+        SV("%u='2'\t%Ou='二'\t%w='2'\t%Ow='二'\t%a='火'\t%A='火曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{2}, 1}});
+  check(loc,
+        SV("%u='3'\t%Ou='三'\t%w='3'\t%Ow='三'\t%a='水'\t%A='水曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{3}, 1}});
+  check(loc,
+        SV("%u='4'\t%Ou='四'\t%w='4'\t%Ow='四'\t%a='木'\t%A='木曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+  check(loc,
+        SV("%u='5'\t%Ou='五'\t%w='5'\t%Ow='五'\t%a='金'\t%A='金曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{5}, 1}});
+  check(loc,
+        SV("%u='6'\t%Ou='六'\t%w='6'\t%Ow='六'\t%a='土'\t%A='土曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{6}, 1}});
+  check(loc,
+        SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{7}, 1}});
+#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test_valid_values() {
+  test_valid_month<CharT>();
+  test_valid_weekday<CharT>();
+}
+
+template <class CharT>
+static void test() {
+  test_no_chrono_specs<CharT>();
+  test_invalid_values<CharT>();
+  test_valid_values<CharT>();
+  check_invalid_types<CharT>(
+      {SV("a"), SV("A"), SV("b"), SV("B"), SV("h"), SV("m"), SV("u"), SV("w"), SV("Om"), SV("Ou"), SV("Ow")},
+      std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+
+  check_exception(
+      "Expected '%' or '}' in the chrono format-string",
+      SV("{:A"),
+      std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check_exception(
+      "The chrono-specs contains a '{'",
+      SV("{:%%{"),
+      std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check_exception(
+      "End of input while parsing the modifier chrono conversion-spec",
+      SV("{:%"),
+      std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check_exception(
+      "End of input while parsing the modifier E",
+      SV("{:%E"),
+      std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+  check_exception(
+      "End of input while parsing the modifier O",
+      SV("{:%O"),
+      std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+
+  // Precision not allowed
+  check_exception(
+      "Expected '%' or '}' in the chrono format-string",
+      SV("{:.3}"),
+      std::chrono::month_weekday{std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{0}, 1}});
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.syn/formatter.weekday_index.pass.cpp b/libcxx/test/std/time/time.syn/formatter.weekday_index.pass.cpp
new file mode 100644
index 0000000000000..8923147091f8c
--- /dev/null
+++ b/libcxx/test/std/time/time.syn/formatter.weekday_index.pass.cpp
@@ -0,0 +1,410 @@
+//===----------------------------------------------------------------------===//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// template<class charT> struct formatter<chrono::weekday_index, charT>;
+
+#include <chrono>
+#include <format>
+
+#include <cassert>
+#include <concepts>
+#include <locale>
+#include <iostream>
+#include <type_traits>
+
+#include "formatter_tests.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+template <class CharT>
+static void test_no_chrono_specs() {
+  using namespace std::literals::chrono_literals;
+
+  // Valid weekday valid index
+  check(SV("Sun[1]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
+
+  // Invalid weekday valid index
+  check(SV("8 is not a valid weekday[1]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+  check(SV("255 is not a valid weekday[1]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+
+  // Valid weekday invalid index
+  check(SV("Sun[0 is not a valid index]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
+  check(SV("Sun[6 is not a valid index]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 6});
+  check(SV("Sun[255 is not a valid index]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 255});
+
+  // Invalid weekday invalid index
+  check(SV("8 is not a valid weekday[0 is not a valid index]"),
+        SV("{}"),
+        std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
+  check(SV("127 is not a valid weekday[6 is not a valid index]"),
+        SV("{}"),
+        std::chrono::weekday_indexed{std::chrono::weekday(127), 6});
+  check(SV("255 is not a valid weekday[255 is not a valid index]"),
+        SV("{}"),
+        std::chrono::weekday_indexed{std::chrono::weekday(255), 255});
+}
+
+template <class CharT>
+static void test_valid_values() {
+  constexpr std::basic_string_view<CharT> fmt =
+      SV("{:%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}");
+  constexpr std::basic_string_view<CharT> lfmt =
+      SV("{:L%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"),
+        fmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
+  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Mon'\t%A='Monday'\n"),
+        fmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(1), 1});
+  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Tue'\t%A='Tuesday'\n"),
+        fmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(2), 2});
+  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Wed'\t%A='Wednesday'\n"),
+        fmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(3), 3});
+  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Thu'\t%A='Thursday'\n"),
+        fmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(4), 4});
+  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Fri'\t%A='Friday'\n"),
+        fmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(5), 5});
+  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sat'\t%A='Saturday'\n"),
+        fmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(6), 6});
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"),
+        fmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(7), 7});
+
+  // Use the global locale (fr_FR)
+#if defined(__APPLE__)
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
+  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Lun'\t%A='Lundi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(1), 1});
+  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Mar'\t%A='Mardi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(2), 2});
+  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Mer'\t%A='Mercredi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(3), 3});
+  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Jeu'\t%A='Jeudi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(4), 4});
+  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Ven'\t%A='Vendredi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(5), 5});
+  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sam'\t%A='Samedi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(6), 6});
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(7), 7});
+#else  // defined(__APPLE__)
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
+  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='lun.'\t%A='lundi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(1), 1});
+  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='mar.'\t%A='mardi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(2), 2});
+  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='mer.'\t%A='mercredi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(3), 3});
+  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='jeu.'\t%A='jeudi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(4), 4});
+  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='ven.'\t%A='vendredi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(5), 5});
+  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='sam.'\t%A='samedi'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(6), 6});
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(7), 7});
+#endif // defined(__APPLE__)
+
+  // Use supplied locale (ja_JP).
+  // This locale has a 
diff erent alternate, but not on all platforms
+#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX)
+  check(loc,
+        SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
+  check(loc,
+        SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='月'\t%A='月曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(1), 1});
+  check(loc,
+        SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='火'\t%A='火曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(2), 2});
+  check(loc,
+        SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='水'\t%A='水曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(3), 3});
+  check(loc,
+        SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='木'\t%A='木曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(4), 4});
+  check(loc,
+        SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='金'\t%A='金曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(5), 5});
+  check(loc,
+        SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='土'\t%A='土曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(6), 6});
+  check(loc,
+        SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(7), 7});
+#else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)
+  check(loc,
+        SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
+  check(loc,
+        SV("%u='1'\t%Ou='一'\t%w='1'\t%Ow='一'\t%a='月'\t%A='月曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(1), 1});
+  check(loc,
+        SV("%u='2'\t%Ou='二'\t%w='2'\t%Ow='二'\t%a='火'\t%A='火曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(2), 2});
+  check(loc,
+        SV("%u='3'\t%Ou='三'\t%w='3'\t%Ow='三'\t%a='水'\t%A='水曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(3), 3});
+  check(loc,
+        SV("%u='4'\t%Ou='四'\t%w='4'\t%Ow='四'\t%a='木'\t%A='木曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(4), 4});
+  check(loc,
+        SV("%u='5'\t%Ou='五'\t%w='5'\t%Ow='五'\t%a='金'\t%A='金曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(5), 5});
+  check(loc,
+        SV("%u='6'\t%Ou='六'\t%w='6'\t%Ow='六'\t%a='土'\t%A='土曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(6), 6});
+  check(loc,
+        SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::weekday_indexed{std::chrono::weekday(7), 7});
+#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test_invalid_values() {
+  // Test that %a and %A throw an exception.
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%a}"),
+                  std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%a}"),
+                  std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%A}"),
+                  std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%A}"),
+                  std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  { // Invalid weekday, can't test %a and %A
+    constexpr std::basic_string_view<CharT> fmt  = SV("{:%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");
+    constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");
+#if defined(__APPLE__)
+    // Non localized output using C-locale
+    check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
+    check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+    check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
+          fmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
+    check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
+          fmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+
+    // Use the global locale (fr_FR)
+    check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
+    check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+    check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
+          lfmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
+    check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
+          lfmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+
+    // Use supplied locale (ja_JP). This locale has a 
diff erent alternate.
+    check(
+        loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
+    check(
+        loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+    check(loc,
+          SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
+          lfmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
+    check(loc,
+          SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
+          lfmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+#elif defined(_AIX) //  defined(__APPLE__)
+    // Non localized output using C-locale
+    check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
+    check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+    check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
+    check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+
+    // Use the global locale (fr_FR)
+    check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
+    check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+    check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
+    check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+
+    // Use supplied locale (ja_JP). This locale has a 
diff erent alternate.
+    check(
+        loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
+    check(
+        loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+    check(loc,
+          SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"),
+          lfmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
+    check(loc,
+          SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"),
+          lfmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+#else               // defined(__APPLE__)
+    // Non localized output using C-locale
+    check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
+    check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+    check(
+        SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
+    check(
+        SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+
+    // Use the global locale (fr_FR)
+    check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
+    check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+    check(
+        SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
+    check(
+        SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+
+    // Use supplied locale (ja_JP). This locale has a 
diff erent alternate.
+    check(loc,
+          SV("%u='1'\t%Ou='一'\t%w='8'\t%Ow='八'\n"),
+          lfmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
+    check(loc,
+          SV("%u='1'\t%Ou='一'\t%w='8'\t%Ow='八'\n"),
+          lfmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
+    check(loc,
+          SV("%u='3'\t%Ou='三'\t%w='255'\t%Ow='255'\n"),
+          lfmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
+    check(loc,
+          SV("%u='3'\t%Ou='三'\t%w='255'\t%Ow='255'\n"),
+          lfmt,
+          std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
+#endif              // defined(__APPLE__)
+  }
+
+  { // Valid weekday, tests %a and %A
+    constexpr std::basic_string_view<CharT> fmt  = SV("{:%%a='%a'%t%%A='%A'%n}");
+    constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%a='%a'%t%%A='%A'%n}");
+
+    // Non localized output using C-locale
+    check(SV("%a='Sun'\t%A='Sunday'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
+    check(SV("%a='Sun'\t%A='Sunday'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6});
+
+    // Use the global locale (fr_FR)
+#if defined(__APPLE__)
+    check(SV("%a='Dim'\t%A='Dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
+    check(SV("%a='Dim'\t%A='Dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6});
+#else  // defined(__APPLE__)
+    check(SV("%a='dim.'\t%A='dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
+    check(SV("%a='dim.'\t%A='dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6});
+#endif // defined(__APPLE__)
+
+    // Use supplied locale (ja_JP)
+    check(loc, SV("%a='日'\t%A='日曜日'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
+    check(loc, SV("%a='日'\t%A='日曜日'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6});
+  }
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test() {
+  test_no_chrono_specs<CharT>();
+  test_valid_values<CharT>();
+  test_invalid_values<CharT>();
+  check_invalid_types<CharT>({SV("a"), SV("A"), SV("t"), SV("u"), SV("w"), SV("Ou"), SV("Ow")},
+                             std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
+
+  check_exception("Expected '%' or '}' in the chrono format-string",
+                  SV("{:A"),
+                  std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
+  check_exception(
+      "The chrono-specs contains a '{'", SV("{:%%{"), std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
+  check_exception("End of input while parsing the modifier chrono conversion-spec",
+                  SV("{:%"),
+                  std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
+  check_exception("End of input while parsing the modifier E",
+                  SV("{:%E"),
+                  std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
+  check_exception("End of input while parsing the modifier O",
+                  SV("{:%O"),
+                  std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
+
+  // Precision not allowed
+  check_exception("Expected '%' or '}' in the chrono format-string",
+                  SV("{:.3}"),
+                  std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.syn/formatter.weekday_last.pass.cpp b/libcxx/test/std/time/time.syn/formatter.weekday_last.pass.cpp
new file mode 100644
index 0000000000000..9c2ec9caa2496
--- /dev/null
+++ b/libcxx/test/std/time/time.syn/formatter.weekday_last.pass.cpp
@@ -0,0 +1,311 @@
+//===----------------------------------------------------------------------===//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// template<class charT> struct formatter<chrono::weekday_last, charT>;
+
+#include <chrono>
+#include <format>
+
+#include <cassert>
+#include <concepts>
+#include <locale>
+#include <iostream>
+#include <type_traits>
+
+#include "formatter_tests.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+template <class CharT>
+static void test_no_chrono_specs() {
+  using namespace std::literals::chrono_literals;
+
+  // Valid day
+  check(SV("Sun[last]"), SV("{}"), std::chrono::weekday_last{std::chrono::weekday(0)});
+
+  // Invalid day
+  check(SV("8 is not a valid weekday[last]"), SV("{}"), std::chrono::weekday_last{std::chrono::weekday(8)});
+}
+
+template <class CharT>
+static void test_valid_values() {
+  constexpr std::basic_string_view<CharT> fmt =
+      SV("{:%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}");
+  constexpr std::basic_string_view<CharT> lfmt =
+      SV("{:L%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"),
+        fmt,
+        std::chrono::weekday_last{std::chrono::weekday(0)});
+  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Mon'\t%A='Monday'\n"),
+        fmt,
+        std::chrono::weekday_last{std::chrono::weekday(1)});
+  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Tue'\t%A='Tuesday'\n"),
+        fmt,
+        std::chrono::weekday_last{std::chrono::weekday(2)});
+  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Wed'\t%A='Wednesday'\n"),
+        fmt,
+        std::chrono::weekday_last{std::chrono::weekday(3)});
+  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Thu'\t%A='Thursday'\n"),
+        fmt,
+        std::chrono::weekday_last{std::chrono::weekday(4)});
+  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Fri'\t%A='Friday'\n"),
+        fmt,
+        std::chrono::weekday_last{std::chrono::weekday(5)});
+  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sat'\t%A='Saturday'\n"),
+        fmt,
+        std::chrono::weekday_last{std::chrono::weekday(6)});
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"),
+        fmt,
+        std::chrono::weekday_last{std::chrono::weekday(7)});
+
+  // Use the global locale (fr_FR)
+#if defined(__APPLE__)
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(0)});
+  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Lun'\t%A='Lundi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(1)});
+  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Mar'\t%A='Mardi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(2)});
+  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Mer'\t%A='Mercredi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(3)});
+  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Jeu'\t%A='Jeudi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(4)});
+  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Ven'\t%A='Vendredi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(5)});
+  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sam'\t%A='Samedi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(6)});
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(7)});
+#else  // defined(__APPLE__)
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(0)});
+  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='lun.'\t%A='lundi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(1)});
+  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='mar.'\t%A='mardi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(2)});
+  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='mer.'\t%A='mercredi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(3)});
+  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='jeu.'\t%A='jeudi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(4)});
+  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='ven.'\t%A='vendredi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(5)});
+  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='sam.'\t%A='samedi'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(6)});
+  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(7)});
+#endif // defined(__APPLE__)
+
+  // Use supplied locale (ja_JP).
+  // This locale has a 
diff erent alternate, but not on all platforms
+#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX)
+  check(loc,
+        SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(0)});
+  check(loc,
+        SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='月'\t%A='月曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(1)});
+  check(loc,
+        SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='火'\t%A='火曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(2)});
+  check(loc,
+        SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='水'\t%A='水曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(3)});
+  check(loc,
+        SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='木'\t%A='木曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(4)});
+  check(loc,
+        SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='金'\t%A='金曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(5)});
+  check(loc,
+        SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='土'\t%A='土曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(6)});
+  check(loc,
+        SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(7)});
+#else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)
+  check(loc,
+        SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(0)});
+  check(loc,
+        SV("%u='1'\t%Ou='一'\t%w='1'\t%Ow='一'\t%a='月'\t%A='月曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(1)});
+  check(loc,
+        SV("%u='2'\t%Ou='二'\t%w='2'\t%Ow='二'\t%a='火'\t%A='火曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(2)});
+  check(loc,
+        SV("%u='3'\t%Ou='三'\t%w='3'\t%Ow='三'\t%a='水'\t%A='水曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(3)});
+  check(loc,
+        SV("%u='4'\t%Ou='四'\t%w='4'\t%Ow='四'\t%a='木'\t%A='木曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(4)});
+  check(loc,
+        SV("%u='5'\t%Ou='五'\t%w='5'\t%Ow='五'\t%a='金'\t%A='金曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(5)});
+  check(loc,
+        SV("%u='6'\t%Ou='六'\t%w='6'\t%Ow='六'\t%a='土'\t%A='土曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(6)});
+  check(loc,
+        SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(7)});
+#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test_invalid_values() {
+  // Test that %a and %A throw an exception.
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%a}"),
+                  std::chrono::weekday_last{std::chrono::weekday(8)});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%a}"),
+                  std::chrono::weekday_last{std::chrono::weekday(255)});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%A}"),
+                  std::chrono::weekday_last{std::chrono::weekday(8)});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%A}"),
+                  std::chrono::weekday_last{std::chrono::weekday(255)});
+
+  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");
+  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+#if defined(__APPLE__)
+  // Non localized output using C-locale
+  check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(8)});
+  check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(255)});
+
+  // Use the global locale (fr_FR)
+  check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});
+  check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});
+
+  // Use supplied locale (ja_JP). This locale has a 
diff erent alternate.
+  check(loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});
+  check(loc,
+        SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
+        lfmt,
+        std::chrono::weekday_last{std::chrono::weekday(255)});
+#elif defined(_AIX) // defined(__APPLE__)
+  // Non localized output using C-locale
+  check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(8)});
+  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(255)});
+
+  // Use the global locale (fr_FR)
+  check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});
+  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});
+
+  // Use supplied locale (ja_JP). This locale has a 
diff erent alternate.
+  check(loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});
+  check(loc, SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});
+#else               //  defined(__APPLE__)
+  // Non localized output using C-locale
+  check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(8)});
+  check(SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(255)});
+
+  // Use the global locale (fr_FR)
+  check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});
+  check(SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});
+
+  // Use supplied locale (ja_JP). This locale has a 
diff erent alternate.
+  check(loc, SV("%u='1'\t%Ou='一'\t%w='8'\t%Ow='八'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});
+  check(loc, SV("%u='3'\t%Ou='三'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});
+#endif              // defined(__APPLE__)
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test() {
+  test_no_chrono_specs<CharT>();
+  test_valid_values<CharT>();
+  test_invalid_values<CharT>();
+  check_invalid_types<CharT>({SV("a"), SV("A"), SV("t"), SV("u"), SV("w"), SV("Ou"), SV("Ow")},
+                             std::chrono::weekday_last{std::chrono::weekday(0)});
+
+  check_exception(
+      "Expected '%' or '}' in the chrono format-string", SV("{:A"), std::chrono::weekday_last{std::chrono::weekday(0)});
+  check_exception("The chrono-specs contains a '{'", SV("{:%%{"), std::chrono::weekday_last{std::chrono::weekday(0)});
+  check_exception("End of input while parsing the modifier chrono conversion-spec",
+                  SV("{:%"),
+                  std::chrono::weekday_last{std::chrono::weekday(0)});
+  check_exception(
+      "End of input while parsing the modifier E", SV("{:%E"), std::chrono::weekday_last{std::chrono::weekday(0)});
+  check_exception(
+      "End of input while parsing the modifier O", SV("{:%O"), std::chrono::weekday_last{std::chrono::weekday(0)});
+
+  // Precision not allowed
+  check_exception("Expected '%' or '}' in the chrono format-string",
+                  SV("{:.3}"),
+                  std::chrono::weekday_last{std::chrono::weekday(0)});
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.syn/formatter.year_month.pass.cpp b/libcxx/test/std/time/time.syn/formatter.year_month.pass.cpp
new file mode 100644
index 0000000000000..9edca556f4550
--- /dev/null
+++ b/libcxx/test/std/time/time.syn/formatter.year_month.pass.cpp
@@ -0,0 +1,288 @@
+//===----------------------------------------------------------------------===//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// template<class charT> struct formatter<chrono::year_month, charT>;
+
+#include <chrono>
+#include <format>
+
+#include <cassert>
+#include <concepts>
+#include <locale>
+#include <iostream>
+#include <type_traits>
+
+#include "formatter_tests.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "string_literal.h"
+#include "test_macros.h"
+
+template <class CharT>
+static void test_no_chrono_specs() {
+  // Valid month
+  check(SV("1970/Jan"), SV("{}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
+  check(SV("*1970/Jan*"), SV("{:*^10}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
+  check(SV("*1970/Jan"), SV("{:*>9}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
+
+  // Invalid month_day
+  check(SV("1970/0 is not a valid month"),
+        SV("{}"),
+        std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
+  check(SV("*1970/0 is not a valid month*"),
+        SV("{:*^29}"),
+        std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
+}
+
+template <class CharT>
+static void test_invalid_values() {
+  // Test that %b and %B throw an exception.
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%b}"),
+                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
+
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%B}"),
+                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
+}
+
+template <class CharT>
+static void test_valid_values() {
+  constexpr std::basic_string_view<CharT> fmt = SV(
+      "{:"
+      "%%b='%b'%t"
+      "%%B='%B'%t"
+      "%%C='%C'%t"
+      "%%h='%h'%t"
+      "%%y='%y'%t"
+      "%%Y='%Y'%t"
+      "%%EC='%EC'%t"
+      "%%Ey='%Ey'%t"
+      "%%EY='%EY'%t"
+      "%%Oy='%Oy'%t"
+      "%n}");
+
+  constexpr std::basic_string_view<CharT> lfmt = SV(
+      "{:L"
+      "%%b='%b'%t"
+      "%%B='%B'%t"
+      "%%C='%C'%t"
+      "%%h='%h'%t"
+      "%%y='%y'%t"
+      "%%Y='%Y'%t"
+      "%%EC='%EC'%t"
+      "%%Ey='%Ey'%t"
+      "%%EY='%EY'%t"
+      "%%Oy='%Oy'%t"
+      "%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(SV("%b='Jan'\t"
+           "%B='January'\t"
+           "%C='19'\t"
+           "%h='Jan'\t"
+           "%y='70'\t"
+           "%Y='1970'\t"
+           "%EC='19'\t"
+           "%Ey='70'\t"
+           "%EY='1970'\t"
+           "%Oy='70'\t"
+           "\n"),
+        fmt,
+        std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
+
+  check(SV("%b='May'\t"
+           "%B='May'\t"
+           "%C='20'\t"
+           "%h='May'\t"
+           "%y='04'\t"
+           "%Y='2004'\t"
+           "%EC='20'\t"
+           "%Ey='04'\t"
+           "%EY='2004'\t"
+           "%Oy='04'\t"
+           "\n"),
+        fmt,
+        std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
+
+  // Use the global locale (fr_FR)
+  check(SV(
+#if defined(__APPLE__)
+            "%b='jan'\t"
+#else
+            "%b='janv.'\t"
+#endif
+            "%B='janvier'\t"
+            "%C='19'\t"
+#if defined(__APPLE__)
+            "%h='jan'\t"
+#else
+            "%h='janv.'\t"
+#endif
+            "%y='70'\t"
+            "%Y='1970'\t"
+            "%EC='19'\t"
+            "%Ey='70'\t"
+            "%EY='1970'\t"
+            "%Oy='70'\t"
+            "\n"),
+        lfmt,
+        std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
+
+  check(SV("%b='mai'\t"
+           "%B='mai'\t"
+           "%C='20'\t"
+           "%h='mai'\t"
+           "%y='04'\t"
+           "%Y='2004'\t"
+           "%EC='20'\t"
+           "%Ey='04'\t"
+           "%EY='2004'\t"
+           "%Oy='04'\t"
+           "\n"),
+        lfmt,
+        std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
+
+  // Use supplied locale (ja_JP)
+  check(loc,
+        SV(
+#if defined(_WIN32)
+            "%b='1'\t"
+#elif defined(_AIX)      // defined(_WIN32)
+            "%b='1月'\t"
+#elif defined(__APPLE__) // defined(_WIN32)
+            "%b=' 1'\t"
+#else                    // defined(_WIN32)
+            "%b=' 1月'\t"
+#endif                   // defined(_WIN32)
+            "%B='1月'\t"
+            "%C='19'\t"
+#if defined(_WIN32)
+            "%h='1'\t"
+#elif defined(_AIX)      // defined(_WIN32)
+            "%h='1月'\t"
+#elif defined(__APPLE__) // defined(_WIN32)
+            "%h=' 1'\t"
+#else                    // defined(_WIN32)
+            "%h=' 1月'\t"
+#endif                   // defined(_WIN32)
+            "%y='70'\t"
+            "%Y='1970'\t"
+#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+            "%EC='19'\t"
+            "%Ey='70'\t"
+            "%EY='1970'\t"
+            "%Oy='70'\t"
+#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+            "%EC='昭和'\t"
+            "%Ey='45'\t"
+            "%EY='昭和45年'\t"
+            "%Oy='七十'\t"
+#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+            "\n"),
+        lfmt,
+        std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
+
+  check(loc,
+        SV(
+
+#if defined(_WIN32)
+            "%b='5'\t"
+#elif defined(_AIX)      // defined(_WIN32)
+            "%b='5月'\t"
+#elif defined(__APPLE__) // defined(_WIN32)
+            "%b=' 5'\t"
+#else                    // defined(_WIN32)
+            "%b=' 5月'\t"
+#endif                   // defined(_WIN32)
+            "%B='5月'\t"
+            "%C='20'\t"
+#if defined(_WIN32)
+            "%h='5'\t"
+#elif defined(_AIX)      // defined(_WIN32)
+            "%h='5月'\t"
+#elif defined(__APPLE__) // defined(_WIN32)
+            "%h=' 5'\t"
+#else                    // defined(_WIN32)
+            "%h=' 5月'\t"
+#endif                   // defined(_WIN32)
+            "%y='04'\t"
+            "%Y='2004'\t"
+#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+            "%EC='20'\t"
+            "%Ey='04'\t"
+            "%EY='2004'\t"
+            "%Oy='04'\t"
+#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+            "%EC='平成'\t"
+            "%Ey='16'\t"
+            "%EY='平成16年'\t"
+            "%Oy='四'\t"
+#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+            "\n"),
+        lfmt,
+        std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test() {
+  test_no_chrono_specs<CharT>();
+  test_invalid_values<CharT>();
+  test_valid_values<CharT>();
+
+  check_invalid_types<CharT>(
+      {SV("b"), SV("B"), SV("C"), SV("EC"), SV("Ey"), SV("EY"), SV("h"), SV("m"), SV("Om"), SV("Oy"), SV("y"), SV("Y")},
+      std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
+
+  check_exception("Expected '%' or '}' in the chrono format-string",
+                  SV("{:A"),
+                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
+  check_exception("The chrono-specs contains a '{'",
+                  SV("{:%%{"),
+                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
+  check_exception("End of input while parsing the modifier chrono conversion-spec",
+                  SV("{:%"),
+                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
+  check_exception("End of input while parsing the modifier E",
+                  SV("{:%E"),
+                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
+  check_exception("End of input while parsing the modifier O",
+                  SV("{:%O"),
+                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
+
+  // Precision not allowed
+  check_exception("Expected '%' or '}' in the chrono format-string",
+                  SV("{:.3}"),
+                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp b/libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp
new file mode 100644
index 0000000000000..a795511d0f84f
--- /dev/null
+++ b/libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp
@@ -0,0 +1,1080 @@
+//===----------------------------------------------------------------------===//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Investigate Windows issues.
+// UNSUPPORTED: msvc, target={{.+}}-windows-gnu
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// template<class charT> struct formatter<chrono::year_month_day, charT>;
+
+#include <chrono>
+#include <format>
+
+#include <cassert>
+#include <concepts>
+#include <locale>
+#include <iostream>
+#include <type_traits>
+
+#include "formatter_tests.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "string_literal.h"
+#include "test_macros.h"
+
+template <class CharT>
+static void test_no_chrono_specs() {
+  // Valid year, valid month, valid day
+  check(SV("1970-01-31"),
+        SV("{}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{31}});
+  check(SV("*1970-01-31*"),
+        SV("{:*^12}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{31}});
+  check(SV("*1970-01-31"),
+        SV("{:*>11}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{31}});
+
+  // Valid year, valid month, invalid day
+  check(SV("1970-02-31 is not a valid date"),
+        SV("{}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{31}});
+  check(SV("*1970-02-31 is not a valid date*"),
+        SV("{:*^32}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{31}});
+  check(SV("*1970-02-31 is not a valid date"),
+        SV("{:*>31}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{31}});
+
+  // Valid year, invalid month, valid day
+  check(SV("1970-00-31 is not a valid date"),
+        SV("{}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check(SV("*1970-00-31 is not a valid date*"),
+        SV("{:*^32}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check(SV("*1970-00-31 is not a valid date"),
+        SV("{:*>31}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+
+  // Valid year, invalid month, invalid day
+  check(SV("1970-00-32 is not a valid date"),
+        SV("{}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{32}});
+  check(SV("*1970-00-32 is not a valid date*"),
+        SV("{:*^32}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{32}});
+  check(SV("*1970-00-32 is not a valid date"),
+        SV("{:*>31}"),
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{32}});
+
+  // Invalid year, valid month, valid day
+  check(SV("-32768-01-31 is not a valid date"),
+        SV("{}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+  check(SV("*-32768-01-31 is not a valid date*"),
+        SV("{:*^34}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+  check(SV("*-32768-01-31 is not a valid date"),
+        SV("{:*>33}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  // Invalid year, valid month, invalid day
+  check(SV("-32768-01-32 is not a valid date"),
+        SV("{}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{32}});
+  check(SV("*-32768-01-32 is not a valid date*"),
+        SV("{:*^34}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{32}});
+  check(SV("*-32768-01-32 is not a valid date"),
+        SV("{:*>33}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{32}});
+
+  // Invalid year, invalid month, valid day
+  check(SV("-32768-00-31 is not a valid date"),
+        SV("{}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::day{31}});
+  check(SV("*-32768-00-31 is not a valid date*"),
+        SV("{:*^34}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::day{31}});
+  check(SV("*-32768-00-31 is not a valid date"),
+        SV("{:*>33}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::day{31}});
+
+  // Invalid year, invalid month, invalid day
+  check(SV("-32768-00-32 is not a valid date"),
+        SV("{}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::day{32}});
+  check(SV("*-32768-00-32 is not a valid date*"),
+        SV("{:*^34}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::day{32}});
+  check(SV("*-32768-00-32 is not a valid date"),
+        SV("{:*>33}"),
+        std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::day{32}});
+}
+
+// TODO FMT Should x throw?
+template <class CharT>
+static void test_invalid_values() {
+  // Test that %a, %A, %b, %B, %h, %j, %u, %U, %V, %w, %W, %Ou, %OU, %OV, %Ow, and %OW throw an exception.
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%A}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%A}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%A}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%A}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%A}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%a}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%a}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%a}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%a}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a weekday name needs a valid weekday",
+                  SV("{:%a}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%B}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%B}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{13}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%B}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{255}, std::chrono::day{31}});
+
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%b}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{200}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%b}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{13}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%b}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{255}, std::chrono::day{31}});
+
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%h}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%h}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{13}, std::chrono::day{31}});
+  check_exception("formatting a month name from an invalid month number",
+                  SV("{:%h}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{255}, std::chrono::day{31}});
+
+  check_exception("formatting a day of year needs a valid date",
+                  SV("{:%j}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a day of year needs a valid date",
+                  SV("{:%j}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a day of year needs a valid date",
+                  SV("{:%j}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a day of year needs a valid date",
+                  SV("{:%j}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a day of year needs a valid date",
+                  SV("{:%j}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%u}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%u}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%u}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%u}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%u}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%U}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%U}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%U}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%U}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%U}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%V}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%V}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%V}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%V}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%V}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%w}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%w}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%w}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%w}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%w}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%W}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%W}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%W}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%W}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%W}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%Ou}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%Ou}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%Ou}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%Ou}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%Ou}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OU}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OU}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OU}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OU}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OU}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OV}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OV}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OV}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OV}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OV}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%Ow}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%Ow}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%Ow}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%Ow}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a weekday needs a valid weekday",
+                  SV("{:%Ow}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OW}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{0}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OW}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{32}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OW}"),
+                  std::chrono::year_month_day{
+                      std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{29}}); // not a leap year
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OW}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}});
+  check_exception("formatting a week of year needs a valid date",
+                  SV("{:%OW}"),
+                  std::chrono::year_month_day{std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::day{31}});
+}
+
+template <class CharT>
+static void test_valid_md_values() {
+  constexpr std::basic_string_view<CharT> fmt =
+      SV("{:%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%t%%d='%d'%t%%e='%e'%t%%Od='%Od'%t%%Oe='%Oe'%n}");
+  constexpr std::basic_string_view<CharT> lfmt =
+      SV("{:L%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%t%%d='%d'%t%%e='%e'%t%%Od='%Od'%t%%Oe='%Oe'%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(SV("%b='Jan'\t%B='January'\t%h='Jan'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{0}});
+  check(SV("%b='Feb'\t%B='February'\t%h='Feb'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::February, std::chrono::day{1}});
+  check(SV("%b='Mar'\t%B='March'\t%h='Mar'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='09'\t%Oe=' 9'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::March, std::chrono::day{9}});
+  check(SV("%b='Apr'\t%B='April'\t%h='Apr'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::April, std::chrono::day{10}});
+  check(SV("%b='May'\t%B='May'\t%h='May'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::May, std::chrono::day{28}});
+  check(SV("%b='Jun'\t%B='June'\t%h='Jun'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='29'\t%Oe='29'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::June, std::chrono::day{29}});
+  check(SV("%b='Jul'\t%B='July'\t%h='Jul'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::July, std::chrono::day{30}});
+  check(SV("%b='Aug'\t%B='August'\t%h='Aug'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::August, std::chrono::day{31}});
+  check(SV("%b='Sep'\t%B='September'\t%h='Sep'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='32'\t%Oe='32'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::September, std::chrono::day{32}});
+  check(SV("%b='Oct'\t%B='October'\t%h='Oct'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='99'\t%Oe='99'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::October, std::chrono::day{99}});
+#if defined(_AIX)
+  check(SV("%b='Nov'\t%B='November'\t%h='Nov'\t%m='11'\t%Om='11'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::November, std::chrono::day{100}});
+  check(SV("%b='Dec'\t%B='December'\t%h='Dec'\t%m='12'\t%Om='12'\t%d='55'\t%e='55'\t%Od='55'\t%Oe='55'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::December, std::chrono::day{255}});
+#else  //  defined(_AIX)
+  check(SV("%b='Nov'\t%B='November'\t%h='Nov'\t%m='11'\t%Om='11'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::November, std::chrono::day{100}});
+  check(SV("%b='Dec'\t%B='December'\t%h='Dec'\t%m='12'\t%Om='12'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        fmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::December, std::chrono::day{255}});
+#endif //  defined(_AIX)
+
+  // Use the global locale (fr_FR)
+#if defined(__APPLE__)
+  check(SV("%b='jan'\t%B='janvier'\t%h='jan'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{0}});
+  check(SV("%b='fév'\t%B='février'\t%h='fév'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::February, std::chrono::day{1}});
+  check(SV("%b='mar'\t%B='mars'\t%h='mar'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='09'\t%Oe=' 9'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::March, std::chrono::day{9}});
+  check(SV("%b='avr'\t%B='avril'\t%h='avr'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::April, std::chrono::day{10}});
+  check(SV("%b='mai'\t%B='mai'\t%h='mai'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::May, std::chrono::day{28}});
+  check(SV("%b='jui'\t%B='juin'\t%h='jui'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='29'\t%Oe='29'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::June, std::chrono::day{29}});
+  check(SV("%b='jul'\t%B='juillet'\t%h='jul'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::July, std::chrono::day{30}});
+  check(SV("%b='aoû'\t%B='août'\t%h='aoû'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::August, std::chrono::day{31}});
+  check(SV("%b='sep'\t%B='septembre'\t%h='sep'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='32'\t%Oe='32'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::September, std::chrono::day{32}});
+  check(SV("%b='oct'\t%B='octobre'\t%h='oct'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='99'\t%Oe='99'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::October, std::chrono::day{99}});
+  check(SV("%b='nov'\t%B='novembre'\t%h='nov'\t%m='11'\t%Om='11'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::November, std::chrono::day{100}});
+  check(SV("%b='déc'\t%B='décembre'\t%h='déc'\t%m='12'\t%Om='12'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::December, std::chrono::day{255}});
+#else    // defined(__APPLE__)
+  check(SV("%b='janv.'\t%B='janvier'\t%h='janv.'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{0}});
+  check(SV("%b='févr.'\t%B='février'\t%h='févr.'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::February, std::chrono::day{1}});
+  check(SV("%b='mars'\t%B='mars'\t%h='mars'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='09'\t%Oe=' 9'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::March, std::chrono::day{9}});
+  check(
+#  if defined(_WIN32) || defined(_AIX)
+      SV("%b='avr.'\t%B='avril'\t%h='avr.'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+#  else  // defined(_WIN32) || defined(_AIX)
+      SV("%b='avril'\t%B='avril'\t%h='avril'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+#  endif // defined(_WIN32) || defined(_AIX)
+      lfmt,
+      std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::April, std::chrono::day{10}});
+  check(SV("%b='mai'\t%B='mai'\t%h='mai'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::May, std::chrono::day{28}});
+  check(SV("%b='juin'\t%B='juin'\t%h='juin'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='29'\t%Oe='29'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::June, std::chrono::day{29}});
+  check(SV("%b='juil.'\t%B='juillet'\t%h='juil.'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::July, std::chrono::day{30}});
+  check(SV("%b='août'\t%B='août'\t%h='août'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::August, std::chrono::day{31}});
+  check(SV("%b='sept.'\t%B='septembre'\t%h='sept.'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='32'\t%Oe='32'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::September, std::chrono::day{32}});
+  check(SV("%b='oct.'\t%B='octobre'\t%h='oct.'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='99'\t%Oe='99'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::October, std::chrono::day{99}});
+#  if defined(_AIX)
+  check(SV("%b='nov.'\t%B='novembre'\t%h='nov.'\t%m='11'\t%Om='11'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::November, std::chrono::day{100}});
+  check(SV("%b='déc.'\t%B='décembre'\t%h='déc.'\t%m='12'\t%Om='12'\t%d='55'\t%e='55'\t%Od='55'\t%Oe='55'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::December, std::chrono::day{255}});
+#  else  //   defined(_AIX)
+  check(SV("%b='nov.'\t%B='novembre'\t%h='nov.'\t%m='11'\t%Om='11'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::November, std::chrono::day{100}});
+  check(SV("%b='déc.'\t%B='décembre'\t%h='déc.'\t%m='12'\t%Om='12'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::December, std::chrono::day{255}});
+#  endif //   defined(_AIX)
+#endif   // defined(__APPLE__)
+
+  // Use supplied locale (ja_JP)
+#if defined(_WIN32)
+  check(loc,
+        SV("%b='1'\t%B='1月'\t%h='1'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='〇'\t%Oe='〇'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{0}});
+  check(loc,
+        SV("%b='2'\t%B='2月'\t%h='2'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='一'\t%Oe='一'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::February, std::chrono::day{1}});
+  check(loc,
+        SV("%b='3'\t%B='3月'\t%h='3'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='九'\t%Oe='九'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::March, std::chrono::day{9}});
+  check(loc,
+        SV("%b='4'\t%B='4月'\t%h='4'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='十'\t%Oe='十'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::April, std::chrono::day{10}});
+  check(loc,
+        SV("%b='5'\t%B='5月'\t%h='5'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='二十八'\t%Oe='二十八'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::May, std::chrono::day{28}});
+  check(loc,
+        SV("%b='6'\t%B='6月'\t%h='6'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='二十九'\t%Oe='二十九'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::June, std::chrono::day{29}});
+  check(loc,
+        SV("%b='7'\t%B='7月'\t%h='7'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='三十'\t%Oe='三十'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::July, std::chrono::day{30}});
+  check(loc,
+        SV("%b='8'\t%B='8月'\t%h='8'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='三十一'\t%Oe='三十一'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::August, std::chrono::day{31}});
+  check(loc,
+        SV("%b='9'\t%B='9月'\t%h='9'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='三十二'\t%Oe='三十二'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::September, std::chrono::day{32}});
+  check(loc,
+        SV("%b='10'\t%B='10月'\t%h='10'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='九十九'\t%Oe='九十九'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::October, std::chrono::day{99}});
+  check(loc,
+        SV("%b='11'\t%B='11月'\t%h='11'\t%m='11'\t%Om='11'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::November, std::chrono::day{100}});
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::December, std::chrono::day{255}});
+#elif defined(_AIX)      // defined(_WIN32)
+  check(loc,
+        SV("%b='1月'\t%B='1月'\t%h='1月'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{0}});
+  check(loc,
+        SV("%b='2月'\t%B='2月'\t%h='2月'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::February, std::chrono::day{1}});
+  check(loc,
+        SV("%b='3月'\t%B='3月'\t%h='3月'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='09'\t%Oe=' 9'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::March, std::chrono::day{9}});
+  check(loc,
+        SV("%b='4月'\t%B='4月'\t%h='4月'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::April, std::chrono::day{10}});
+  check(loc,
+        SV("%b='5月'\t%B='5月'\t%h='5月'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::May, std::chrono::day{28}});
+  check(loc,
+        SV("%b='6月'\t%B='6月'\t%h='6月'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='29'\t%Oe='29'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::June, std::chrono::day{29}});
+  check(loc,
+        SV("%b='7月'\t%B='7月'\t%h='7月'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::July, std::chrono::day{30}});
+  check(loc,
+        SV("%b='8月'\t%B='8月'\t%h='8月'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::August, std::chrono::day{31}});
+  check(loc,
+        SV("%b='9月'\t%B='9月'\t%h='9月'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='32'\t%Oe='32'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::September, std::chrono::day{32}});
+  check(loc,
+        SV("%b='10月'\t%B='10月'\t%h='10月'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='99'\t%Oe='99'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::October, std::chrono::day{99}});
+  check(loc,
+        SV("%b='11月'\t%B='11月'\t%h='11月'\t%m='11'\t%Om='11'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::November, std::chrono::day{100}});
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='12'\t%d='55'\t%e='55'\t%Od='55'\t%Oe='55'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::December, std::chrono::day{255}});
+#elif defined(__APPLE__) // defined(_WIN32)
+  check(loc,
+        SV("%b=' 1'\t%B='1月'\t%h=' 1'\t%m='01'\t%Om='01'\t%d='00'\t%e=' 0'\t%Od='00'\t%Oe=' 0'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{0}});
+  check(loc,
+        SV("%b=' 2'\t%B='2月'\t%h=' 2'\t%m='02'\t%Om='02'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::February, std::chrono::day{1}});
+  check(loc,
+        SV("%b=' 3'\t%B='3月'\t%h=' 3'\t%m='03'\t%Om='03'\t%d='09'\t%e=' 9'\t%Od='09'\t%Oe=' 9'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::March, std::chrono::day{9}});
+  check(loc,
+        SV("%b=' 4'\t%B='4月'\t%h=' 4'\t%m='04'\t%Om='04'\t%d='10'\t%e='10'\t%Od='10'\t%Oe='10'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::April, std::chrono::day{10}});
+  check(loc,
+        SV("%b=' 5'\t%B='5月'\t%h=' 5'\t%m='05'\t%Om='05'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::May, std::chrono::day{28}});
+  check(loc,
+        SV("%b=' 6'\t%B='6月'\t%h=' 6'\t%m='06'\t%Om='06'\t%d='29'\t%e='29'\t%Od='29'\t%Oe='29'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::June, std::chrono::day{29}});
+  check(loc,
+        SV("%b=' 7'\t%B='7月'\t%h=' 7'\t%m='07'\t%Om='07'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::July, std::chrono::day{30}});
+  check(loc,
+        SV("%b=' 8'\t%B='8月'\t%h=' 8'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::August, std::chrono::day{31}});
+  check(loc,
+        SV("%b=' 9'\t%B='9月'\t%h=' 9'\t%m='09'\t%Om='09'\t%d='32'\t%e='32'\t%Od='32'\t%Oe='32'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::September, std::chrono::day{32}});
+  check(loc,
+        SV("%b='10'\t%B='10月'\t%h='10'\t%m='10'\t%Om='10'\t%d='99'\t%e='99'\t%Od='99'\t%Oe='99'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::October, std::chrono::day{99}});
+  check(loc,
+        SV("%b='11'\t%B='11月'\t%h='11'\t%m='11'\t%Om='11'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::November, std::chrono::day{100}});
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::December, std::chrono::day{255}});
+#else                    // defined(_WIN32)
+  check(loc,
+        SV("%b=' 1月'\t%B='1月'\t%h=' 1月'\t%m='01'\t%Om='一'\t%d='00'\t%e=' 0'\t%Od='〇'\t%Oe='〇'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{0}});
+  check(loc,
+        SV("%b=' 2月'\t%B='2月'\t%h=' 2月'\t%m='02'\t%Om='二'\t%d='01'\t%e=' 1'\t%Od='一'\t%Oe='一'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::February, std::chrono::day{1}});
+  check(loc,
+        SV("%b=' 3月'\t%B='3月'\t%h=' 3月'\t%m='03'\t%Om='三'\t%d='09'\t%e=' 9'\t%Od='九'\t%Oe='九'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::March, std::chrono::day{9}});
+  check(loc,
+        SV("%b=' 4月'\t%B='4月'\t%h=' 4月'\t%m='04'\t%Om='四'\t%d='10'\t%e='10'\t%Od='十'\t%Oe='十'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::April, std::chrono::day{10}});
+  check(loc,
+        SV("%b=' 5月'\t%B='5月'\t%h=' 5月'\t%m='05'\t%Om='五'\t%d='28'\t%e='28'\t%Od='二十八'\t%Oe='二十八'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::May, std::chrono::day{28}});
+  check(loc,
+        SV("%b=' 6月'\t%B='6月'\t%h=' 6月'\t%m='06'\t%Om='六'\t%d='29'\t%e='29'\t%Od='二十九'\t%Oe='二十九'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::June, std::chrono::day{29}});
+  check(loc,
+        SV("%b=' 7月'\t%B='7月'\t%h=' 7月'\t%m='07'\t%Om='七'\t%d='30'\t%e='30'\t%Od='三十'\t%Oe='三十'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::July, std::chrono::day{30}});
+  check(loc,
+        SV("%b=' 8月'\t%B='8月'\t%h=' 8月'\t%m='08'\t%Om='八'\t%d='31'\t%e='31'\t%Od='三十一'\t%Oe='三十一'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::August, std::chrono::day{31}});
+  check(loc,
+        SV("%b=' 9月'\t%B='9月'\t%h=' 9月'\t%m='09'\t%Om='九'\t%d='32'\t%e='32'\t%Od='三十二'\t%Oe='三十二'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::September, std::chrono::day{32}});
+  check(loc,
+        SV("%b='10月'\t%B='10月'\t%h='10月'\t%m='10'\t%Om='十'\t%d='99'\t%e='99'\t%Od='九十九'\t%Oe='九十九'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::October, std::chrono::day{99}});
+  check(loc,
+        SV("%b='11月'\t%B='11月'\t%h='11月'\t%m='11'\t%Om='十一'\t%d='100'\t%e='100'\t%Od='100'\t%Oe='100'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::November, std::chrono::day{100}});
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='十二'\t%d='255'\t%e='255'\t%Od='255'\t%Oe='255'\n"),
+        lfmt,
+        std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::December, std::chrono::day{255}});
+#endif                   //  defined(_WIN32)
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test_valid_ymd_values() {
+  constexpr std::basic_string_view<CharT> fmt = SV(
+      "{:"
+      "%%C='%C'%t"
+      "%%D='%D'%t"
+      "%%F='%F'%t"
+      "%%j='%j'%t"
+      "%%g='%g'%t"
+      "%%G='%G'%t"
+      "%%u='%u'%t"
+      "%%U='%U'%t"
+      "%%V='%V'%t"
+      "%%w='%w'%t"
+      "%%W='%W'%t"
+      "%%x='%x'%t"
+      "%%y='%y'%t"
+      "%%Y='%Y'%t"
+      "%%Ex='%Ex'%t"
+      "%%EC='%EC'%t"
+      "%%Ey='%Ey'%t"
+      "%%EY='%EY'%t"
+      "%%Ou='%Ou'%t"
+      "%%OU='%OU'%t"
+      "%%OV='%OV'%t"
+      "%%Ow='%Ow'%t"
+      "%%OW='%OW'%t"
+      "%%Oy='%Oy'%t"
+      "%n}");
+
+  constexpr std::basic_string_view<CharT> lfmt = SV(
+      "{:L"
+      "%%C='%C'%t"
+      "%%D='%D'%t"
+      "%%F='%F'%t"
+      "%%j='%j'%t"
+      "%%g='%g'%t"
+      "%%G='%G'%t"
+      "%%u='%u'%t"
+      "%%U='%U'%t"
+      "%%V='%V'%t"
+      "%%w='%w'%t"
+      "%%W='%W'%t"
+      "%%x='%x'%t"
+      "%%y='%y'%t"
+      "%%Y='%Y'%t"
+      "%%Ex='%Ex'%t"
+      "%%EC='%EC'%t"
+      "%%Ey='%Ey'%t"
+      "%%EY='%EY'%t"
+      "%%Ou='%Ou'%t"
+      "%%OU='%OU'%t"
+      "%%OV='%OV'%t"
+      "%%Ow='%Ow'%t"
+      "%%OW='%OW'%t"
+      "%%Oy='%Oy'%t"
+      "%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(
+      SV("%C='19'\t"
+         "%D='01/01/70'\t"
+         "%F='1970-01-01'\t"
+         "%j='001'\t"
+         "%g='70'\t"
+         "%G='1970'\t"
+         "%u='4'\t"
+         "%U='00'\t"
+         "%V='01'\t"
+         "%w='4'\t"
+         "%W='00'\t"
+         "%x='01/01/70'\t"
+         "%y='70'\t"
+         "%Y='1970'\t"
+         "%Ex='01/01/70'\t"
+         "%EC='19'\t"
+         "%Ey='70'\t"
+         "%EY='1970'\t"
+         "%Ou='4'\t"
+         "%OU='00'\t"
+         "%OV='01'\t"
+         "%Ow='4'\t"
+         "%OW='00'\t"
+         "%Oy='70'\t"
+         "\n"),
+      fmt,
+      std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{1}});
+
+  check(
+      SV("%C='20'\t"
+         "%D='05/29/04'\t"
+         "%F='2004-05-29'\t"
+         "%j='150'\t"
+         "%g='04'\t"
+         "%G='2004'\t"
+         "%u='6'\t"
+         "%U='21'\t"
+         "%V='22'\t"
+         "%w='6'\t"
+         "%W='21'\t"
+         "%x='05/29/04'\t"
+         "%y='04'\t"
+         "%Y='2004'\t"
+         "%Ex='05/29/04'\t"
+         "%EC='20'\t"
+         "%Ey='04'\t"
+         "%EY='2004'\t"
+         "%Ou='6'\t"
+         "%OU='21'\t"
+         "%OV='22'\t"
+         "%Ow='6'\t"
+         "%OW='21'\t"
+         "%Oy='04'\t"
+         "\n"),
+      fmt,
+      std::chrono::year_month_day{std::chrono::year{2004}, std::chrono::May, std::chrono::day{29}});
+
+  // Use the global locale (fr_FR)
+  check(
+      SV("%C='19'\t"
+         "%D='01/01/70'\t"
+         "%F='1970-01-01'\t"
+         "%j='001'\t"
+         "%g='70'\t"
+         "%G='1970'\t"
+         "%u='4'\t"
+         "%U='00'\t"
+         "%V='01'\t"
+         "%w='4'\t"
+         "%W='00'\t"
+#if defined(__APPLE__)
+         "%x='01.01.1970'\t"
+#else
+         "%x='01/01/1970'\t"
+#endif
+         "%y='70'\t"
+         "%Y='1970'\t"
+#if defined(__APPLE__)
+         "%Ex='01.01.1970'\t"
+#else
+         "%Ex='01/01/1970'\t"
+#endif
+         "%EC='19'\t"
+         "%Ey='70'\t"
+         "%EY='1970'\t"
+         "%Ou='4'\t"
+         "%OU='00'\t"
+         "%OV='01'\t"
+         "%Ow='4'\t"
+         "%OW='00'\t"
+         "%Oy='70'\t"
+         "\n"),
+      lfmt,
+      std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{1}});
+
+  check(
+      SV("%C='20'\t"
+         "%D='05/29/04'\t"
+         "%F='2004-05-29'\t"
+         "%j='150'\t"
+         "%g='04'\t"
+         "%G='2004'\t"
+         "%u='6'\t"
+         "%U='21'\t"
+         "%V='22'\t"
+         "%w='6'\t"
+         "%W='21'\t"
+#if defined(__APPLE__)
+         "%x='29.05.2004'\t"
+#else
+         "%x='29/05/2004'\t"
+#endif
+         "%y='04'\t"
+         "%Y='2004'\t"
+#if defined(__APPLE__)
+         "%Ex='29.05.2004'\t"
+#else
+         "%Ex='29/05/2004'\t"
+#endif
+         "%EC='20'\t"
+         "%Ey='04'\t"
+         "%EY='2004'\t"
+         "%Ou='6'\t"
+         "%OU='21'\t"
+         "%OV='22'\t"
+         "%Ow='6'\t"
+         "%OW='21'\t"
+         "%Oy='04'\t"
+         "\n"),
+      lfmt,
+      std::chrono::year_month_day{std::chrono::year{2004}, std::chrono::May, std::chrono::day{29}});
+
+  // Use supplied locale (ja_JP)
+  check(
+      loc,
+      SV("%C='19'\t"
+         "%D='01/01/70'\t"
+         "%F='1970-01-01'\t"
+         "%j='001'\t"
+         "%g='70'\t"
+         "%G='1970'\t"
+         "%u='4'\t"
+         "%U='00'\t"
+         "%V='01'\t"
+         "%w='4'\t"
+         "%W='00'\t"
+#if defined(__APPLE__) || defined(_AIX)
+         "%x='1970/01/01'\t"
+#else  // defined(__APPLE__) || defined(_AIX)
+         "%x='1970年01月01日'\t"
+#endif // defined(__APPLE__) || defined(_AIX)
+         "%y='70'\t"
+         "%Y='1970'\t"
+#if defined(__APPLE__) || defined(_AIX)
+         "%Ex='1970/01/01'\t"
+         "%EC='19'\t"
+         "%Ey='70'\t"
+         "%EY='1970'\t"
+         "%Ou='4'\t"
+         "%OU='00'\t"
+         "%OV='01'\t"
+         "%Ow='4'\t"
+         "%OW='00'\t"
+         "%Oy='70'\t"
+#else  // defined(__APPLE__) || defined(_AIX)
+         "%Ex='昭和45年01月01日'\t"
+         "%EC='昭和'\t"
+         "%Ey='45'\t"
+         "%EY='昭和45年'\t"
+         "%Ou='四'\t"
+         "%OU='〇'\t"
+         "%OV='一'\t"
+         "%Ow='四'\t"
+         "%OW='〇'\t"
+         "%Oy='七十'\t"
+#endif // defined(__APPLE__) || defined(_AIX)
+         "\n"),
+      lfmt,
+      std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{1}});
+
+  check(
+      loc,
+      SV("%C='20'\t"
+         "%D='05/29/04'\t"
+         "%F='2004-05-29'\t"
+         "%j='150'\t"
+         "%g='04'\t"
+         "%G='2004'\t"
+         "%u='6'\t"
+         "%U='21'\t"
+         "%V='22'\t"
+         "%w='6'\t"
+         "%W='21'\t"
+#if defined(__APPLE__) || defined(_AIX)
+         "%x='2004/05/29'\t"
+#else  // defined(__APPLE__) || defined(_AIX)
+         "%x='2004年05月29日'\t"
+#endif // defined(__APPLE__) || defined(_AIX)
+         "%y='04'\t"
+         "%Y='2004'\t"
+#if defined(__APPLE__) || defined(_AIX)
+         "%Ex='2004/05/29'\t"
+         "%EC='20'\t"
+         "%Ey='04'\t"
+         "%EY='2004'\t"
+         "%Ou='6'\t"
+         "%OU='21'\t"
+         "%OV='22'\t"
+         "%Ow='6'\t"
+         "%OW='21'\t"
+         "%Oy='04'\t"
+#else  // defined(__APPLE__) || defined(_AIX)
+         "%Ex='平成16年05月29日'\t"
+         "%EC='平成'\t"
+         "%Ey='16'\t"
+         "%EY='平成16年'\t"
+         "%Ou='六'\t"
+         "%OU='二十一'\t"
+         "%OV='二十二'\t"
+         "%Ow='六'\t"
+         "%OW='二十一'\t"
+         "%Oy='四'\t"
+#endif // defined(__APPLE__) || defined(_AIX)
+         "\n"),
+      lfmt,
+      std::chrono::year_month_day{std::chrono::year{2004}, std::chrono::May, std::chrono::day{29}});
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test_valid_values() {
+  // Fields only using month and day.
+  test_valid_md_values<CharT>();
+  // Fields only using year, month, and day.
+  test_valid_ymd_values<CharT>();
+}
+
+template <class CharT>
+static void test() {
+  test_no_chrono_specs<CharT>();
+  test_invalid_values<CharT>();
+  test_valid_values<CharT>();
+  check_invalid_types<CharT>(
+      {SV("a"),  SV("A"),  SV("b"),  SV("B"),  SV("C"),  SV("d"),  SV("D"),  SV("e"),  SV("EC"),
+       SV("Ex"), SV("Ey"), SV("EY"), SV("F"),  SV("g"),  SV("G"),  SV("h"),  SV("j"),  SV("m"),
+       SV("Od"), SV("Oe"), SV("Om"), SV("Ou"), SV("OU"), SV("OV"), SV("Ow"), SV("OW"), SV("Oy"),
+       SV("u"),  SV("U"),  SV("V"),  SV("w"),  SV("W"),  SV("x"),  SV("y"),  SV("Y")},
+      std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{31}});
+
+  check_exception("Expected '%' or '}' in the chrono format-string",
+                  SV("{:A"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{31}});
+  check_exception("The chrono-specs contains a '{'",
+                  SV("{:%%{"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{31}});
+  check_exception("End of input while parsing the modifier chrono conversion-spec",
+                  SV("{:%"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{31}});
+  check_exception("End of input while parsing the modifier E",
+                  SV("{:%E"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{31}});
+  check_exception("End of input while parsing the modifier O",
+                  SV("{:%O"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{31}});
+
+  // Precision not allowed
+  check_exception("Expected '%' or '}' in the chrono format-string",
+                  SV("{:.3}"),
+                  std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::January, std::chrono::day{31}});
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.syn/formatter.year_month_day_last.pass.cpp b/libcxx/test/std/time/time.syn/formatter.year_month_day_last.pass.cpp
new file mode 100644
index 0000000000000..0df69191f47c9
--- /dev/null
+++ b/libcxx/test/std/time/time.syn/formatter.year_month_day_last.pass.cpp
@@ -0,0 +1,932 @@
+//===----------------------------------------------------------------------===//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// template<class charT> struct formatter<chrono::year_month_day_last, charT>;
+
+#include <chrono>
+#include <format>
+
+#include <cassert>
+#include <concepts>
+#include <locale>
+#include <iostream>
+#include <type_traits>
+
+#include "formatter_tests.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "string_literal.h"
+#include "test_macros.h"
+
+template <class CharT>
+static void test_no_chrono_specs() {
+  // Valid year, valid month
+  check(SV("1970/Jan/last"),
+        SV("{}"),
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{1}}});
+  check(SV("*1970/Jan/last*"),
+        SV("{:*^15}"),
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{1}}});
+  check(SV("*1970/Jan/last"),
+        SV("{:*>14}"),
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  // Valid year, invalid month
+  check(SV("1970/0 is not a valid month/last"),
+        SV("{}"),
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check(SV("*1970/0 is not a valid month/last*"),
+        SV("{:*^34}"),
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check(SV("*1970/0 is not a valid month/last"),
+        SV("{:*>33}"),
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+
+  // Invalid year, valid month
+  check(
+      SV("-32768 is not a valid year/Jan/last"),
+      SV("{}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+  check(
+      SV("*-32768 is not a valid year/Jan/last*"),
+      SV("{:*^37}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+  check(
+      SV("*-32768 is not a valid year/Jan/last"),
+      SV("{:*>36}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  // Invalid year, invalid month
+  check(
+      SV("-32768 is not a valid year/0 is not a valid month/last"),
+      SV("{}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check(
+      SV("*-32768 is not a valid year/0 is not a valid month/last*"),
+      SV("{:*^56}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check(
+      SV("*-32768 is not a valid year/0 is not a valid month/last"),
+      SV("{:*>55}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{0}}});
+}
+
+// TODO FMT Should x throw?
+template <class CharT>
+static void test_invalid_values() {
+  // Test that %a, %A, %b, %B, %h, %j, %u, %U, %V, %w, %W, %Ou, %OU, %OV, %Ow, and %OW throw an exception.
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%A}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%A}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%a}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%a}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%B}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%B}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{13}}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%B}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{255}}});
+
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%b}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{200}}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%b}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{13}}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%b}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{255}}});
+
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%h}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%h}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{13}}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%h}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{255}}});
+
+  check_exception(
+      "formatting a day of year needs a valid date",
+      SV("{:%j}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a day of year needs a valid date",
+      SV("{:%j}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%u}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%u}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%U}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%U}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%V}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%V}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%w}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%w}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%W}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%W}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%Ou}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%Ou}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%OU}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%OU}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%OV}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%OV}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%Ow}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%Ow}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%OW}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::month{0}}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%OW}"),
+      std::chrono::year_month_day_last{std::chrono::year{-32768}, std::chrono::month_day_last{std::chrono::month{1}}});
+}
+
+template <class CharT>
+static void test_valid_md_values() {
+  constexpr std::basic_string_view<CharT> fmt =
+      SV("{:%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%t%%d='%d'%t%%e='%e'%t%%Od='%Od'%t%%Oe='%Oe'%n}");
+  constexpr std::basic_string_view<CharT> lfmt =
+      SV("{:L%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%t%%d='%d'%t%%e='%e'%t%%Od='%Od'%t%%Oe='%Oe'%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(SV("%b='Jan'\t%B='January'\t%h='Jan'\t%m='01'\t%Om='01'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+  check(SV("%b='Feb'\t%B='February'\t%h='Feb'\t%m='02'\t%Om='02'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::February}});
+  check(SV("%b='Mar'\t%B='March'\t%h='Mar'\t%m='03'\t%Om='03'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::March}});
+  check(SV("%b='Apr'\t%B='April'\t%h='Apr'\t%m='04'\t%Om='04'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::April}});
+  check(SV("%b='May'\t%B='May'\t%h='May'\t%m='05'\t%Om='05'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::May}});
+  check(SV("%b='Jun'\t%B='June'\t%h='Jun'\t%m='06'\t%Om='06'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::June}});
+  check(SV("%b='Jul'\t%B='July'\t%h='Jul'\t%m='07'\t%Om='07'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::July}});
+  check(SV("%b='Aug'\t%B='August'\t%h='Aug'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::August}});
+  check(SV("%b='Sep'\t%B='September'\t%h='Sep'\t%m='09'\t%Om='09'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::September}});
+  check(SV("%b='Oct'\t%B='October'\t%h='Oct'\t%m='10'\t%Om='10'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::October}});
+  check(SV("%b='Nov'\t%B='November'\t%h='Nov'\t%m='11'\t%Om='11'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::November}});
+  check(SV("%b='Dec'\t%B='December'\t%h='Dec'\t%m='12'\t%Om='12'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        fmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::December}});
+
+  // Use the global locale (fr_FR)
+#if defined(__APPLE__)
+  check(SV("%b='jan'\t%B='janvier'\t%h='jan'\t%m='01'\t%Om='01'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+  check(SV("%b='fév'\t%B='février'\t%h='fév'\t%m='02'\t%Om='02'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::February}});
+  check(SV("%b='mar'\t%B='mars'\t%h='mar'\t%m='03'\t%Om='03'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::March}});
+  check(SV("%b='avr'\t%B='avril'\t%h='avr'\t%m='04'\t%Om='04'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::April}});
+  check(SV("%b='mai'\t%B='mai'\t%h='mai'\t%m='05'\t%Om='05'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::May}});
+  check(SV("%b='jui'\t%B='juin'\t%h='jui'\t%m='06'\t%Om='06'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::June}});
+  check(SV("%b='jul'\t%B='juillet'\t%h='jul'\t%m='07'\t%Om='07'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::July}});
+  check(SV("%b='aoû'\t%B='août'\t%h='aoû'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::August}});
+  check(SV("%b='sep'\t%B='septembre'\t%h='sep'\t%m='09'\t%Om='09'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::September}});
+  check(SV("%b='oct'\t%B='octobre'\t%h='oct'\t%m='10'\t%Om='10'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::October}});
+  check(SV("%b='nov'\t%B='novembre'\t%h='nov'\t%m='11'\t%Om='11'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::November}});
+  check(SV("%b='déc'\t%B='décembre'\t%h='déc'\t%m='12'\t%Om='12'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::December}});
+#else    // defined(__APPLE__)
+  check(SV("%b='janv.'\t%B='janvier'\t%h='janv.'\t%m='01'\t%Om='01'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+  check(SV("%b='févr.'\t%B='février'\t%h='févr.'\t%m='02'\t%Om='02'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::February}});
+  check(SV("%b='mars'\t%B='mars'\t%h='mars'\t%m='03'\t%Om='03'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::March}});
+  check(
+#  if defined(_WIN32) || defined(_AIX)
+      SV("%b='avr.'\t%B='avril'\t%h='avr.'\t%m='04'\t%Om='04'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+#  else  // defined(_WIN32) || defined(_AIX)
+      SV("%b='avril'\t%B='avril'\t%h='avril'\t%m='04'\t%Om='04'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+#  endif // defined(_WIN32) || defined(_AIX)
+      lfmt,
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::April}});
+  check(SV("%b='mai'\t%B='mai'\t%h='mai'\t%m='05'\t%Om='05'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::May}});
+  check(SV("%b='juin'\t%B='juin'\t%h='juin'\t%m='06'\t%Om='06'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::June}});
+  check(SV("%b='juil.'\t%B='juillet'\t%h='juil.'\t%m='07'\t%Om='07'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::July}});
+  check(SV("%b='août'\t%B='août'\t%h='août'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::August}});
+  check(SV("%b='sept.'\t%B='septembre'\t%h='sept.'\t%m='09'\t%Om='09'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::September}});
+  check(SV("%b='oct.'\t%B='octobre'\t%h='oct.'\t%m='10'\t%Om='10'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::October}});
+  check(SV("%b='nov.'\t%B='novembre'\t%h='nov.'\t%m='11'\t%Om='11'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::November}});
+  check(SV("%b='déc.'\t%B='décembre'\t%h='déc.'\t%m='12'\t%Om='12'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::December}});
+#endif   // defined(__APPLE__)
+
+  // Use supplied locale (ja_JP)
+#if defined(_WIN32)
+  check(loc,
+        SV("%b='1'\t%B='1月'\t%h='1'\t%m='01'\t%Om='01'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+  check(loc,
+        SV("%b='2'\t%B='2月'\t%h='2'\t%m='02'\t%Om='02'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::February}});
+  check(loc,
+        SV("%b='3'\t%B='3月'\t%h='3'\t%m='03'\t%Om='03'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::March}});
+  check(loc,
+        SV("%b='4'\t%B='4月'\t%h='4'\t%m='04'\t%Om='04'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::April}});
+  check(loc,
+        SV("%b='5'\t%B='5月'\t%h='5'\t%m='05'\t%Om='05'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::May}});
+  check(loc,
+        SV("%b='6'\t%B='6月'\t%h='6'\t%m='06'\t%Om='06'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::June}});
+  check(loc,
+        SV("%b='7'\t%B='7月'\t%h='7'\t%m='07'\t%Om='07'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::July}});
+  check(loc,
+        SV("%b='8'\t%B='8月'\t%h='8'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::August}});
+  check(loc,
+        SV("%b='9'\t%B='9月'\t%h='9'\t%m='09'\t%Om='09'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::September}});
+  check(loc,
+        SV("%b='10'\t%B='10月'\t%h='10'\t%m='10'\t%Om='10'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::October}});
+  check(loc,
+        SV("%b='11'\t%B='11月'\t%h='11'\t%m='11'\t%Om='11'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::November}});
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::December}});
+#elif defined(_AIX)      // defined(_WIN32)
+  check(loc,
+        SV("%b='1月'\t%B='1月'\t%h='1月'\t%m='01'\t%Om='01'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+  check(loc,
+        SV("%b='2月'\t%B='2月'\t%h='2月'\t%m='02'\t%Om='02'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::February}});
+  check(loc,
+        SV("%b='3月'\t%B='3月'\t%h='3月'\t%m='03'\t%Om='03'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::March}});
+  check(loc,
+        SV("%b='4月'\t%B='4月'\t%h='4月'\t%m='04'\t%Om='04'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::April}});
+  check(loc,
+        SV("%b='5月'\t%B='5月'\t%h='5月'\t%m='05'\t%Om='05'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::May}});
+  check(loc,
+        SV("%b='6月'\t%B='6月'\t%h='6月'\t%m='06'\t%Om='06'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::June}});
+  check(loc,
+        SV("%b='7月'\t%B='7月'\t%h='7月'\t%m='07'\t%Om='07'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::July}});
+  check(loc,
+        SV("%b='8月'\t%B='8月'\t%h='8月'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::August}});
+  check(loc,
+        SV("%b='9月'\t%B='9月'\t%h='9月'\t%m='09'\t%Om='09'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::September}});
+  check(loc,
+        SV("%b='10月'\t%B='10月'\t%h='10月'\t%m='10'\t%Om='10'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::October}});
+  check(loc,
+        SV("%b='11月'\t%B='11月'\t%h='11月'\t%m='11'\t%Om='11'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::November}});
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='12'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::December}});
+#elif defined(__APPLE__) // defined(_WIN32)
+  check(loc,
+        SV("%b=' 1'\t%B='1月'\t%h=' 1'\t%m='01'\t%Om='01'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+  check(loc,
+        SV("%b=' 2'\t%B='2月'\t%h=' 2'\t%m='02'\t%Om='02'\t%d='28'\t%e='28'\t%Od='28'\t%Oe='28'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::February}});
+  check(loc,
+        SV("%b=' 3'\t%B='3月'\t%h=' 3'\t%m='03'\t%Om='03'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::March}});
+  check(loc,
+        SV("%b=' 4'\t%B='4月'\t%h=' 4'\t%m='04'\t%Om='04'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::April}});
+  check(loc,
+        SV("%b=' 5'\t%B='5月'\t%h=' 5'\t%m='05'\t%Om='05'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::May}});
+  check(loc,
+        SV("%b=' 6'\t%B='6月'\t%h=' 6'\t%m='06'\t%Om='06'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::June}});
+  check(loc,
+        SV("%b=' 7'\t%B='7月'\t%h=' 7'\t%m='07'\t%Om='07'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::July}});
+  check(loc,
+        SV("%b=' 8'\t%B='8月'\t%h=' 8'\t%m='08'\t%Om='08'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::August}});
+  check(loc,
+        SV("%b=' 9'\t%B='9月'\t%h=' 9'\t%m='09'\t%Om='09'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::September}});
+  check(loc,
+        SV("%b='10'\t%B='10月'\t%h='10'\t%m='10'\t%Om='10'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::October}});
+  check(loc,
+        SV("%b='11'\t%B='11月'\t%h='11'\t%m='11'\t%Om='11'\t%d='30'\t%e='30'\t%Od='30'\t%Oe='30'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::November}});
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\t%d='31'\t%e='31'\t%Od='31'\t%Oe='31'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::December}});
+#else                    // defined(_WIN32)
+  check(loc,
+        SV("%b=' 1月'\t%B='1月'\t%h=' 1月'\t%m='01'\t%Om='一'\t%d='31'\t%e='31'\t%Od='三十一'\t%Oe='三十一'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+  check(loc,
+        SV("%b=' 2月'\t%B='2月'\t%h=' 2月'\t%m='02'\t%Om='二'\t%d='28'\t%e='28'\t%Od='二十八'\t%Oe='二十八'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::February}});
+  check(loc,
+        SV("%b=' 3月'\t%B='3月'\t%h=' 3月'\t%m='03'\t%Om='三'\t%d='31'\t%e='31'\t%Od='三十一'\t%Oe='三十一'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::March}});
+  check(loc,
+        SV("%b=' 4月'\t%B='4月'\t%h=' 4月'\t%m='04'\t%Om='四'\t%d='30'\t%e='30'\t%Od='三十'\t%Oe='三十'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::April}});
+  check(loc,
+        SV("%b=' 5月'\t%B='5月'\t%h=' 5月'\t%m='05'\t%Om='五'\t%d='31'\t%e='31'\t%Od='三十一'\t%Oe='三十一'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::May}});
+  check(loc,
+        SV("%b=' 6月'\t%B='6月'\t%h=' 6月'\t%m='06'\t%Om='六'\t%d='30'\t%e='30'\t%Od='三十'\t%Oe='三十'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::June}});
+  check(loc,
+        SV("%b=' 7月'\t%B='7月'\t%h=' 7月'\t%m='07'\t%Om='七'\t%d='31'\t%e='31'\t%Od='三十一'\t%Oe='三十一'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::July}});
+  check(loc,
+        SV("%b=' 8月'\t%B='8月'\t%h=' 8月'\t%m='08'\t%Om='八'\t%d='31'\t%e='31'\t%Od='三十一'\t%Oe='三十一'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::August}});
+  check(loc,
+        SV("%b=' 9月'\t%B='9月'\t%h=' 9月'\t%m='09'\t%Om='九'\t%d='30'\t%e='30'\t%Od='三十'\t%Oe='三十'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::September}});
+  check(loc,
+        SV("%b='10月'\t%B='10月'\t%h='10月'\t%m='10'\t%Om='十'\t%d='31'\t%e='31'\t%Od='三十一'\t%Oe='三十一'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::October}});
+  check(loc,
+        SV("%b='11月'\t%B='11月'\t%h='11月'\t%m='11'\t%Om='十一'\t%d='30'\t%e='30'\t%Od='三十'\t%Oe='三十'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::November}});
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='十二'\t%d='31'\t%e='31'\t%Od='三十一'\t%Oe='三十一'\n"),
+        lfmt,
+        std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::December}});
+#endif                   //  defined(_WIN32)
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test_valid_ymd_values() {
+  constexpr std::basic_string_view<CharT> fmt = SV(
+      "{:"
+      "%%C='%C'%t"
+      "%%D='%D'%t"
+      "%%F='%F'%t"
+      "%%j='%j'%t"
+      "%%g='%g'%t"
+      "%%G='%G'%t"
+      "%%u='%u'%t"
+      "%%U='%U'%t"
+      "%%V='%V'%t"
+      "%%w='%w'%t"
+      "%%W='%W'%t"
+      "%%x='%x'%t"
+      "%%y='%y'%t"
+      "%%Y='%Y'%t"
+      "%%Ex='%Ex'%t"
+      "%%EC='%EC'%t"
+      "%%Ey='%Ey'%t"
+      "%%EY='%EY'%t"
+      "%%Ou='%Ou'%t"
+      "%%OU='%OU'%t"
+      "%%OV='%OV'%t"
+      "%%Ow='%Ow'%t"
+      "%%OW='%OW'%t"
+      "%%Oy='%Oy'%t"
+      "%n}");
+
+  constexpr std::basic_string_view<CharT> lfmt = SV(
+      "{:L"
+      "%%C='%C'%t"
+      "%%D='%D'%t"
+      "%%F='%F'%t"
+      "%%j='%j'%t"
+      "%%g='%g'%t"
+      "%%G='%G'%t"
+      "%%u='%u'%t"
+      "%%U='%U'%t"
+      "%%V='%V'%t"
+      "%%w='%w'%t"
+      "%%W='%W'%t"
+      "%%x='%x'%t"
+      "%%y='%y'%t"
+      "%%Y='%Y'%t"
+      "%%Ex='%Ex'%t"
+      "%%EC='%EC'%t"
+      "%%Ey='%Ey'%t"
+      "%%EY='%EY'%t"
+      "%%Ou='%Ou'%t"
+      "%%OU='%OU'%t"
+      "%%OV='%OV'%t"
+      "%%Ow='%Ow'%t"
+      "%%OW='%OW'%t"
+      "%%Oy='%Oy'%t"
+      "%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(
+      SV("%C='19'\t"
+         "%D='01/31/70'\t"
+         "%F='1970-01-31'\t"
+         "%j='031'\t"
+         "%g='70'\t"
+         "%G='1970'\t"
+         "%u='6'\t"
+         "%U='04'\t"
+         "%V='05'\t"
+         "%w='6'\t"
+         "%W='04'\t"
+         "%x='01/31/70'\t"
+         "%y='70'\t"
+         "%Y='1970'\t"
+         "%Ex='01/31/70'\t"
+         "%EC='19'\t"
+         "%Ey='70'\t"
+         "%EY='1970'\t"
+         "%Ou='6'\t"
+         "%OU='04'\t"
+         "%OV='05'\t"
+         "%Ow='6'\t"
+         "%OW='04'\t"
+         "%Oy='70'\t"
+         "\n"),
+      fmt,
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+
+  check(
+      SV("%C='20'\t"
+         "%D='05/31/04'\t"
+         "%F='2004-05-31'\t"
+         "%j='152'\t"
+         "%g='04'\t"
+         "%G='2004'\t"
+         "%u='1'\t"
+         "%U='22'\t"
+         "%V='23'\t"
+         "%w='1'\t"
+         "%W='22'\t"
+         "%x='05/31/04'\t"
+         "%y='04'\t"
+         "%Y='2004'\t"
+         "%Ex='05/31/04'\t"
+         "%EC='20'\t"
+         "%Ey='04'\t"
+         "%EY='2004'\t"
+         "%Ou='1'\t"
+         "%OU='22'\t"
+         "%OV='23'\t"
+         "%Ow='1'\t"
+         "%OW='22'\t"
+         "%Oy='04'\t"
+         "\n"),
+      fmt,
+      std::chrono::year_month_day_last{std::chrono::year{2004}, std::chrono::month_day_last{std::chrono::May}});
+
+  // Use the global locale (fr_FR)
+  check(
+      SV("%C='19'\t"
+         "%D='01/31/70'\t"
+         "%F='1970-01-31'\t"
+         "%j='031'\t"
+         "%g='70'\t"
+         "%G='1970'\t"
+         "%u='6'\t"
+         "%U='04'\t"
+         "%V='05'\t"
+         "%w='6'\t"
+         "%W='04'\t"
+#if defined(__APPLE__)
+         "%x='31.01.1970'\t"
+#else
+         "%x='31/01/1970'\t"
+#endif
+         "%y='70'\t"
+         "%Y='1970'\t"
+#if defined(__APPLE__)
+         "%Ex='31.01.1970'\t"
+#else
+         "%Ex='31/01/1970'\t"
+#endif
+         "%EC='19'\t"
+         "%Ey='70'\t"
+         "%EY='1970'\t"
+         "%Ou='6'\t"
+         "%OU='04'\t"
+         "%OV='05'\t"
+         "%Ow='6'\t"
+         "%OW='04'\t"
+         "%Oy='70'\t"
+         "\n"),
+      lfmt,
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+
+  check(
+      SV("%C='20'\t"
+         "%D='05/31/04'\t"
+         "%F='2004-05-31'\t"
+         "%j='152'\t"
+         "%g='04'\t"
+         "%G='2004'\t"
+         "%u='1'\t"
+         "%U='22'\t"
+         "%V='23'\t"
+         "%w='1'\t"
+         "%W='22'\t"
+#if defined(__APPLE__)
+         "%x='31.05.2004'\t"
+#else
+         "%x='31/05/2004'\t"
+#endif
+         "%y='04'\t"
+         "%Y='2004'\t"
+#if defined(__APPLE__)
+         "%Ex='31.05.2004'\t"
+#else
+         "%Ex='31/05/2004'\t"
+#endif
+         "%EC='20'\t"
+         "%Ey='04'\t"
+         "%EY='2004'\t"
+         "%Ou='1'\t"
+         "%OU='22'\t"
+         "%OV='23'\t"
+         "%Ow='1'\t"
+         "%OW='22'\t"
+         "%Oy='04'\t"
+         "\n"),
+      lfmt,
+      std::chrono::year_month_day_last{std::chrono::year{2004}, std::chrono::month_day_last{std::chrono::May}});
+
+  // Use supplied locale (ja_JP)
+  check(
+      loc,
+      SV("%C='19'\t"
+         "%D='01/31/70'\t"
+         "%F='1970-01-31'\t"
+         "%j='031'\t"
+         "%g='70'\t"
+         "%G='1970'\t"
+         "%u='6'\t"
+         "%U='04'\t"
+         "%V='05'\t"
+         "%w='6'\t"
+         "%W='04'\t"
+#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%x='1970/01/31'\t"
+#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%x='1970年01月31日'\t"
+#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%y='70'\t"
+         "%Y='1970'\t"
+#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%Ex='1970/01/31'\t"
+         "%EC='19'\t"
+         "%Ey='70'\t"
+         "%EY='1970'\t"
+         "%Ou='6'\t"
+         "%OU='04'\t"
+         "%OV='05'\t"
+         "%Ow='6'\t"
+         "%OW='04'\t"
+         "%Oy='70'\t"
+#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%Ex='昭和45年01月31日'\t"
+         "%EC='昭和'\t"
+         "%Ey='45'\t"
+         "%EY='昭和45年'\t"
+         "%Ou='六'\t"
+         "%OU='四'\t"
+         "%OV='五'\t"
+         "%Ow='六'\t"
+         "%OW='四'\t"
+         "%Oy='七十'\t"
+#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "\n"),
+      lfmt,
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+
+  check(
+      loc,
+      SV("%C='20'\t"
+         "%D='05/31/04'\t"
+         "%F='2004-05-31'\t"
+         "%j='152'\t"
+         "%g='04'\t"
+         "%G='2004'\t"
+         "%u='1'\t"
+         "%U='22'\t"
+         "%V='23'\t"
+         "%w='1'\t"
+         "%W='22'\t"
+#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%x='2004/05/31'\t"
+#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%x='2004年05月31日'\t"
+#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%y='04'\t"
+         "%Y='2004'\t"
+#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%Ex='2004/05/31'\t"
+         "%EC='20'\t"
+         "%Ey='04'\t"
+         "%EY='2004'\t"
+         "%Ou='1'\t"
+         "%OU='22'\t"
+         "%OV='23'\t"
+         "%Ow='1'\t"
+         "%OW='22'\t"
+         "%Oy='04'\t"
+#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%Ex='平成16年05月31日'\t"
+         "%EC='平成'\t"
+         "%Ey='16'\t"
+         "%EY='平成16年'\t"
+         "%Ou='一'\t"
+         "%OU='二十二'\t"
+         "%OV='二十三'\t"
+         "%Ow='一'\t"
+         "%OW='二十二'\t"
+         "%Oy='四'\t"
+#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "\n"),
+      lfmt,
+      std::chrono::year_month_day_last{std::chrono::year{2004}, std::chrono::month_day_last{std::chrono::May}});
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test_valid_values() {
+  // Fields only using month and day.
+  test_valid_md_values<CharT>();
+  // Fields only using year, month, and day.
+  test_valid_ymd_values<CharT>();
+}
+
+template <class CharT>
+static void test() {
+  test_no_chrono_specs<CharT>();
+  test_invalid_values<CharT>();
+  test_valid_values<CharT>();
+  check_invalid_types<CharT>(
+      {SV("a"),  SV("A"),  SV("b"),  SV("B"),  SV("C"),  SV("d"),  SV("D"),  SV("e"),  SV("EC"),
+       SV("Ex"), SV("Ey"), SV("EY"), SV("F"),  SV("g"),  SV("G"),  SV("h"),  SV("j"),  SV("m"),
+       SV("Od"), SV("Oe"), SV("Om"), SV("Ou"), SV("OU"), SV("OV"), SV("Ow"), SV("OW"), SV("Oy"),
+       SV("u"),  SV("U"),  SV("V"),  SV("w"),  SV("W"),  SV("x"),  SV("y"),  SV("Y")},
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+
+  check_exception(
+      "Expected '%' or '}' in the chrono format-string",
+      SV("{:A"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+  check_exception(
+      "The chrono-specs contains a '{'",
+      SV("{:%%{"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+  check_exception(
+      "End of input while parsing the modifier chrono conversion-spec",
+      SV("{:%"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+  check_exception(
+      "End of input while parsing the modifier E",
+      SV("{:%E"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+  check_exception(
+      "End of input while parsing the modifier O",
+      SV("{:%O"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+
+  // Precision not allowed
+  check_exception(
+      "Expected '%' or '}' in the chrono format-string",
+      SV("{:.3}"),
+      std::chrono::year_month_day_last{std::chrono::year{1970}, std::chrono::month_day_last{std::chrono::January}});
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.syn/formatter.year_month_weekday.pass.cpp b/libcxx/test/std/time/time.syn/formatter.year_month_weekday.pass.cpp
new file mode 100644
index 0000000000000..7189789de4f97
--- /dev/null
+++ b/libcxx/test/std/time/time.syn/formatter.year_month_weekday.pass.cpp
@@ -0,0 +1,735 @@
+//===----------------------------------------------------------------------===//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// template<class charT> struct formatter<chrono::year_month_weekday, charT>;
+
+#include <chrono>
+#include <format>
+
+#include <cassert>
+#include <concepts>
+#include <locale>
+#include <iostream>
+#include <type_traits>
+
+#include "formatter_tests.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "string_literal.h"
+#include "test_macros.h"
+
+template <class CharT>
+static void test_no_chrono_specs() {
+  // Valid year, valid month, valid day, valid index
+  check(SV("1970/Jan/Mon[1]"),
+        SV("{}"),
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check(SV("*1970/Jan/Mon[1]"),
+        SV("{:*>16}"),
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check(SV("*1970/Jan/Mon[1]*"),
+        SV("{:*^17}"),
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+
+  // Valid year, valid month, valid day, invalid index
+  check(SV("1970/Jan/Mon[7 is not a valid index]"),
+        SV("{}"),
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
+
+  // Valid year, valid month, invalid day, valid index
+  check(SV("1970/Jan/13 is not a valid weekday[1]"),
+        SV("{}"),
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+
+  // Valid year, valid month, invalid day, invalid index
+  check(SV("1970/Jan/13 is not a valid weekday[7 is not a valid index]"),
+        SV("{}"),
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 7}});
+
+  // Valid year, invalid month, valid day, invalid index
+  check(SV("1970/0 is not a valid month/Mon[7 is not a valid index]"),
+        SV("{}"),
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
+
+  // Valid year, invalid month, invalid day, valid index
+  check(SV("1970/0 is not a valid month/13 is not a valid weekday[1]"),
+        SV("{}"),
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+
+  // Valid year, invalid month, invalid day, invalid index
+  check(SV("1970/0 is not a valid month/13 is not a valid weekday[7 is not a valid index]"),
+        SV("{}"),
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 7}});
+
+  // Invalid year, valid month, valid day, valid index
+  check(
+      SV("-32768 is not a valid year/Jan/Mon[1]"),
+      SV("{}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+
+  // Invalid year, valid month, valid day, invalid index
+  check(
+      SV("-32768 is not a valid year/Jan/Mon[7 is not a valid index]"),
+      SV("{}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
+
+  // Invalid year, valid month, invalid day, valid index
+  check(
+      SV("-32768 is not a valid year/Jan/13 is not a valid weekday[1]"),
+      SV("{}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+
+  // Invalid year, valid month, invalid day, invalid index
+  check(
+      SV("-32768 is not a valid year/Jan/13 is not a valid weekday[7 is not a valid index]"),
+      SV("{}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 7}});
+
+  // Invalid year, invalid month, valid day, invalid index
+  check(
+      SV("-32768 is not a valid year/0 is not a valid month/Mon[7 is not a valid index]"),
+      SV("{}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
+
+  // Invalid year, invalid month, invalid day, valid index
+  check(
+      SV("-32768 is not a valid year/0 is not a valid month/13 is not a valid weekday[1]"),
+      SV("{}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+
+  // Invalid year, invalid month, invalid day, invalid index
+  check(
+      SV("-32768 is not a valid year/0 is not a valid month/13 is not a valid weekday[7 is not a valid index]"),
+      SV("{}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 7}});
+}
+
+// TODO FMT Should x throw?
+template <class CharT>
+static void test_invalid_values() {
+  // Test that %a, %A, %b, %B, %h, %j, %u, %U, %V, %w, %W, %Ou, %OU, %OV, %Ow, and %OW throw an exception.
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%a}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%A}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%b}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%B}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%h}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+
+  check_exception(
+      "formatting a day of year needs a valid date",
+      SV("{:%j}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
+  check_exception(
+      "formatting a day of year needs a valid date",
+      SV("{:%j}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+  check_exception(
+      "formatting a day of year needs a valid date",
+      SV("{:%j}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check_exception(
+      "formatting a day of year needs a valid date",
+      SV("{:%j}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%u}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%U}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%U}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%U}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%U}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%V}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%V}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%V}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%V}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%w}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%W}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%W}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%W}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check_exception(
+      "formatting a week of year needs a valid date",
+      SV("{:%W}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+}
+
+template <class CharT>
+static void test_valid_md_values() {
+  constexpr std::basic_string_view<CharT> fmt =
+      SV("{:%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%t%%d='%d'%t%%e='%e'%t%%Od='%Od'%t%%Oe='%Oe'%n}");
+  constexpr std::basic_string_view<CharT> lfmt =
+      SV("{:L%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%t%%d='%d'%t%%e='%e'%t%%Od='%Od'%t%%Oe='%Oe'%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+
+  check(SV("%b='Jan'\t%B='January'\t%h='Jan'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        fmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+  check(SV("%b='Dec'\t%B='December'\t%h='Dec'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
+        fmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
+
+  // Use the global locale (fr_FR)
+#if defined(__APPLE__)
+  check(SV("%b='jan'\t%B='janvier'\t%h='jan'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+
+  check(SV("%b='déc'\t%B='décembre'\t%h='déc'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
+
+#else  // defined(__APPLE__)
+  check(SV("%b='janv.'\t%B='janvier'\t%h='janv.'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+  check(SV("%b='déc.'\t%B='décembre'\t%h='déc.'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
+
+#endif // defined(__APPLE__)
+
+  // Use supplied locale (ja_JP)
+#if defined(_WIN32)
+  check(loc,
+        SV("%b='1'\t%B='1月'\t%h='1'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
+
+#elif defined(_AIX)      // defined(_WIN32)
+  check(loc,
+        SV("%b='1月'\t%B='1月'\t%h='1月'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
+
+#elif defined(__APPLE__) // defined(_WIN32)
+  check(loc,
+        SV("%b=' 1'\t%B='1月'\t%h=' 1'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+
+  check(loc,
+        SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
+
+#else                    // defined(_WIN32)
+  check(loc,
+        SV("%b=' 1月'\t%B='1月'\t%h=' 1月'\t%m='01'\t%Om='一'\t%d='01'\t%e=' 1'\t%Od='一'\t%Oe='一'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+
+  check(loc,
+        SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='十二'\t%d='20'\t%e='20'\t%Od='二十'\t%Oe='二十'\n"),
+        lfmt,
+        std::chrono::year_month_weekday{
+            std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
+
+#endif                   //  defined(_WIN32)
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test_valid_ymd_values() {
+  constexpr std::basic_string_view<CharT> fmt = SV(
+      "{:"
+      "%%C='%C'%t"
+      "%%D='%D'%t"
+      "%%F='%F'%t"
+      "%%j='%j'%t"
+      "%%g='%g'%t"
+      "%%G='%G'%t"
+      "%%u='%u'%t"
+      "%%U='%U'%t"
+      "%%V='%V'%t"
+      "%%w='%w'%t"
+      "%%W='%W'%t"
+      "%%x='%x'%t"
+      "%%y='%y'%t"
+      "%%Y='%Y'%t"
+      "%%Ex='%Ex'%t"
+      "%%EC='%EC'%t"
+      "%%Ey='%Ey'%t"
+      "%%EY='%EY'%t"
+      "%%Ou='%Ou'%t"
+      "%%OU='%OU'%t"
+      "%%OV='%OV'%t"
+      "%%Ow='%Ow'%t"
+      "%%OW='%OW'%t"
+      "%%Oy='%Oy'%t"
+      "%n}");
+
+  constexpr std::basic_string_view<CharT> lfmt = SV(
+      "{:L"
+      "%%C='%C'%t"
+      "%%D='%D'%t"
+      "%%F='%F'%t"
+      "%%j='%j'%t"
+      "%%g='%g'%t"
+      "%%G='%G'%t"
+      "%%u='%u'%t"
+      "%%U='%U'%t"
+      "%%V='%V'%t"
+      "%%w='%w'%t"
+      "%%W='%W'%t"
+      "%%x='%x'%t"
+      "%%y='%y'%t"
+      "%%Y='%Y'%t"
+      "%%Ex='%Ex'%t"
+      "%%EC='%EC'%t"
+      "%%Ey='%Ey'%t"
+      "%%EY='%EY'%t"
+      "%%Ou='%Ou'%t"
+      "%%OU='%OU'%t"
+      "%%OV='%OV'%t"
+      "%%Ow='%Ow'%t"
+      "%%OW='%OW'%t"
+      "%%Oy='%Oy'%t"
+      "%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(
+      SV("%C='19'\t"
+         "%D='01/01/70'\t"
+         "%F='1970-01-01'\t"
+         "%j='001'\t"
+         "%g='70'\t"
+         "%G='1970'\t"
+         "%u='4'\t"
+         "%U='00'\t"
+         "%V='01'\t"
+         "%w='4'\t"
+         "%W='00'\t"
+         "%x='01/01/70'\t"
+         "%y='70'\t"
+         "%Y='1970'\t"
+         "%Ex='01/01/70'\t"
+         "%EC='19'\t"
+         "%Ey='70'\t"
+         "%EY='1970'\t"
+         "%Ou='4'\t"
+         "%OU='00'\t"
+         "%OV='01'\t"
+         "%Ow='4'\t"
+         "%OW='00'\t"
+         "%Oy='70'\t"
+         "\n"),
+      fmt,
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+
+  check(
+      SV("%C='20'\t"
+         "%D='05/29/04'\t"
+         "%F='2004-05-29'\t"
+         "%j='150'\t"
+         "%g='04'\t"
+         "%G='2004'\t"
+         "%u='6'\t"
+         "%U='21'\t"
+         "%V='22'\t"
+         "%w='6'\t"
+         "%W='21'\t"
+         "%x='05/29/04'\t"
+         "%y='04'\t"
+         "%Y='2004'\t"
+         "%Ex='05/29/04'\t"
+         "%EC='20'\t"
+         "%Ey='04'\t"
+         "%EY='2004'\t"
+         "%Ou='6'\t"
+         "%OU='21'\t"
+         "%OV='22'\t"
+         "%Ow='6'\t"
+         "%OW='21'\t"
+         "%Oy='04'\t"
+         "\n"),
+      fmt,
+      std::chrono::year_month_weekday{
+          std::chrono::year{2004}, std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{6}, 5}});
+
+  // Use the global locale (fr_FR)
+  check(
+      SV("%C='19'\t"
+         "%D='01/01/70'\t"
+         "%F='1970-01-01'\t"
+         "%j='001'\t"
+         "%g='70'\t"
+         "%G='1970'\t"
+         "%u='4'\t"
+         "%U='00'\t"
+         "%V='01'\t"
+         "%w='4'\t"
+         "%W='00'\t"
+#if defined(__APPLE__)
+         "%x='01.01.1970'\t"
+#else
+         "%x='01/01/1970'\t"
+#endif
+         "%y='70'\t"
+         "%Y='1970'\t"
+#if defined(__APPLE__)
+         "%Ex='01.01.1970'\t"
+#else
+         "%Ex='01/01/1970'\t"
+#endif
+         "%EC='19'\t"
+         "%Ey='70'\t"
+         "%EY='1970'\t"
+         "%Ou='4'\t"
+         "%OU='00'\t"
+         "%OV='01'\t"
+         "%Ow='4'\t"
+         "%OW='00'\t"
+         "%Oy='70'\t"
+         "\n"),
+      lfmt,
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+
+  check(
+      SV("%C='20'\t"
+         "%D='05/29/04'\t"
+         "%F='2004-05-29'\t"
+         "%j='150'\t"
+         "%g='04'\t"
+         "%G='2004'\t"
+         "%u='6'\t"
+         "%U='21'\t"
+         "%V='22'\t"
+         "%w='6'\t"
+         "%W='21'\t"
+#if defined(__APPLE__)
+         "%x='29.05.2004'\t"
+#else
+         "%x='29/05/2004'\t"
+#endif
+         "%y='04'\t"
+         "%Y='2004'\t"
+#if defined(__APPLE__)
+         "%Ex='29.05.2004'\t"
+#else
+         "%Ex='29/05/2004'\t"
+#endif
+         "%EC='20'\t"
+         "%Ey='04'\t"
+         "%EY='2004'\t"
+         "%Ou='6'\t"
+         "%OU='21'\t"
+         "%OV='22'\t"
+         "%Ow='6'\t"
+         "%OW='21'\t"
+         "%Oy='04'\t"
+         "\n"),
+      lfmt,
+      std::chrono::year_month_weekday{
+          std::chrono::year{2004}, std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{6}, 5}});
+
+  // Use supplied locale (ja_JP)
+  check(
+      loc,
+      SV("%C='19'\t"
+         "%D='01/01/70'\t"
+         "%F='1970-01-01'\t"
+         "%j='001'\t"
+         "%g='70'\t"
+         "%G='1970'\t"
+         "%u='4'\t"
+         "%U='00'\t"
+         "%V='01'\t"
+         "%w='4'\t"
+         "%W='00'\t"
+#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%x='1970/01/01'\t"
+#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%x='1970年01月01日'\t"
+#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%y='70'\t"
+         "%Y='1970'\t"
+#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%Ex='1970/01/01'\t"
+         "%EC='19'\t"
+         "%Ey='70'\t"
+         "%EY='1970'\t"
+         "%Ou='4'\t"
+         "%OU='00'\t"
+         "%OV='01'\t"
+         "%Ow='4'\t"
+         "%OW='00'\t"
+         "%Oy='70'\t"
+#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%Ex='昭和45年01月01日'\t"
+         "%EC='昭和'\t"
+         "%Ey='45'\t"
+         "%EY='昭和45年'\t"
+         "%Ou='四'\t"
+         "%OU='〇'\t"
+         "%OV='一'\t"
+         "%Ow='四'\t"
+         "%OW='〇'\t"
+         "%Oy='七十'\t"
+#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "\n"),
+      lfmt,
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
+
+  check(
+      loc,
+      SV("%C='20'\t"
+         "%D='05/29/04'\t"
+         "%F='2004-05-29'\t"
+         "%j='150'\t"
+         "%g='04'\t"
+         "%G='2004'\t"
+         "%u='6'\t"
+         "%U='21'\t"
+         "%V='22'\t"
+         "%w='6'\t"
+         "%W='21'\t"
+#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%x='2004/05/29'\t"
+#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%x='2004年05月29日'\t"
+#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%y='04'\t"
+         "%Y='2004'\t"
+#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%Ex='2004/05/29'\t"
+         "%EC='20'\t"
+         "%Ey='04'\t"
+         "%EY='2004'\t"
+         "%Ou='6'\t"
+         "%OU='21'\t"
+         "%OV='22'\t"
+         "%Ow='6'\t"
+         "%OW='21'\t"
+         "%Oy='04'\t"
+#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "%Ex='平成16年05月29日'\t"
+         "%EC='平成'\t"
+         "%Ey='16'\t"
+         "%EY='平成16年'\t"
+         "%Ou='六'\t"
+         "%OU='二十一'\t"
+         "%OV='二十二'\t"
+         "%Ow='六'\t"
+         "%OW='二十一'\t"
+         "%Oy='四'\t"
+#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
+         "\n"),
+      lfmt,
+      std::chrono::year_month_weekday{
+          std::chrono::year{2004}, std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{6}, 5}});
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test_valid_values() {
+  // Fields only using month and day.
+  test_valid_md_values<CharT>();
+  // Fields only using year, month, and day.
+  test_valid_ymd_values<CharT>();
+}
+
+template <class CharT>
+static void test() {
+  test_no_chrono_specs<CharT>();
+  test_invalid_values<CharT>();
+  test_valid_values<CharT>();
+  check_invalid_types<CharT>(
+      {SV("a"),  SV("A"),  SV("b"),  SV("B"),  SV("C"),  SV("d"),  SV("D"),  SV("e"),  SV("EC"),
+       SV("Ex"), SV("Ey"), SV("EY"), SV("F"),  SV("g"),  SV("G"),  SV("h"),  SV("j"),  SV("m"),
+       SV("Od"), SV("Oe"), SV("Om"), SV("Ou"), SV("OU"), SV("OV"), SV("Ow"), SV("OW"), SV("Oy"),
+       SV("u"),  SV("U"),  SV("V"),  SV("w"),  SV("W"),  SV("x"),  SV("y"),  SV("Y")},
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+
+  check_exception(
+      "Expected '%' or '}' in the chrono format-string",
+      SV("{:A"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check_exception(
+      "The chrono-specs contains a '{'",
+      SV("{:%%{"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check_exception(
+      "End of input while parsing the modifier chrono conversion-spec",
+      SV("{:%"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check_exception(
+      "End of input while parsing the modifier E",
+      SV("{:%E"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+  check_exception(
+      "End of input while parsing the modifier O",
+      SV("{:%O"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+
+  // Precision not allowed
+  check_exception(
+      "Expected '%' or '}' in the chrono format-string",
+      SV("{:.3}"),
+      std::chrono::year_month_weekday{
+          std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/time/time.syn/formatter.year_month_weekday_last.pass.cpp b/libcxx/test/std/time/time.syn/formatter.year_month_weekday_last.pass.cpp
new file mode 100644
index 0000000000000..50968a39dbe64
--- /dev/null
+++ b/libcxx/test/std/time/time.syn/formatter.year_month_weekday_last.pass.cpp
@@ -0,0 +1,246 @@
+//===----------------------------------------------------------------------===//
+// 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-localization
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT It seems GCC uses too much memory in the CI and fails.
+// UNSUPPORTED: gcc-12
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// template<class charT> struct formatter<chrono::year_month_weekday_last, charT>;
+
+#include <chrono>
+#include <format>
+
+#include <cassert>
+#include <concepts>
+#include <locale>
+#include <iostream>
+#include <type_traits>
+
+#include "formatter_tests.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "string_literal.h"
+#include "test_macros.h"
+
+template <class CharT>
+static void test_no_chrono_specs() {
+  // Valid
+  check(SV("1970/Jan/Mon[last]"),
+        SV("{}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("*1970/Jan/Mon[last]*"),
+        SV("{:*^20}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("*1970/Jan/Mon[last]"),
+        SV("{:*>19}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+
+  // Invalid
+  check(SV("1970/Jan/8 is not a valid weekday[last]"),
+        SV("{}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
+  check(SV("1970/0 is not a valid month/Mon[last]"),
+        SV("{}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("-32768 is not a valid year/Jan/Mon[last]"),
+        SV("{}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+}
+
+template <class CharT>
+static void test_invalid_values() {
+  // *** Invalid weekday ***
+
+  // Weekday name conversion
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%a}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
+  check_exception(
+      "formatting a weekday name needs a valid weekday",
+      SV("{:%A}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
+
+  // Weekday conversion
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%u}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%w}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%Ou}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
+  check_exception(
+      "formatting a weekday needs a valid weekday",
+      SV("{:%Ow}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
+
+  // Day of year field
+  check_exception(
+      "formatting a day of year needs a valid date",
+      SV("{:%j}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
+
+  // Month name conversion
+  check(SV("Jan"),
+        SV("{:%b}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
+  check(SV("Jan"),
+        SV("{:%h}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
+  check(SV("January"),
+        SV("{:%B}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
+
+  // *** Invalid month ***
+
+  // Weekday name conversion
+  check(SV("Mon"),
+        SV("{:%a}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("Monday"),
+        SV("{:%A}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  // Weekday conversion
+  check(SV("1"),
+        SV("{:%u}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("1"),
+        SV("{:%w}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("1"),
+        SV("{:%Ou}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("1"),
+        SV("{:%Ow}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+
+  // Day of year field
+  check_exception(
+      "formatting a day of year needs a valid date",
+      SV("{:%j}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+
+  // Month name conversion
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%b}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%h}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check_exception(
+      "formatting a month name from an invalid month number",
+      SV("{:%B}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+
+  // *** Invalid year ***
+
+  // Weekday name conversion
+  check(SV("Mon"),
+        SV("{:%a}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("Monday"),
+        SV("{:%A}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+
+  // Weekday conversion
+  check(SV("1"),
+        SV("{:%u}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("1"),
+        SV("{:%w}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("1"),
+        SV("{:%Ou}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("1"),
+        SV("{:%Ow}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+
+  // Day of year field
+  check_exception(
+      "formatting a day of year needs a valid date",
+      SV("{:%j}"),
+      std::chrono::year_month_weekday_last{
+          std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+
+  // Month name conversion
+  check(SV("Jan"),
+        SV("{:%b}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("Jan"),
+        SV("{:%h}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+  check(SV("January"),
+        SV("{:%B}"),
+        std::chrono::year_month_weekday_last{
+            std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
+}
+
+template <class CharT>
+static void test() {
+  test_no_chrono_specs<CharT>();
+  test_invalid_values<CharT>();
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp b/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
index 66082889282ba..4e9e526bf032e 100644
--- a/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
@@ -146,19 +146,19 @@ void test_P1361() {
   assert_is_formattable<std::chrono::year, CharT>();
 
   assert_is_formattable<std::chrono::weekday, CharT>();
-  assert_is_not_formattable<std::chrono::weekday_indexed, CharT>();
-  assert_is_not_formattable<std::chrono::weekday_last, CharT>();
-
-  assert_is_not_formattable<std::chrono::month_day, CharT>();
-  assert_is_not_formattable<std::chrono::month_day_last, CharT>();
-  assert_is_not_formattable<std::chrono::month_weekday, CharT>();
-  assert_is_not_formattable<std::chrono::month_weekday_last, CharT>();
-
-  assert_is_not_formattable<std::chrono::year_month, CharT>();
-  assert_is_not_formattable<std::chrono::year_month_day, CharT>();
-  assert_is_not_formattable<std::chrono::year_month_day_last, CharT>();
-  assert_is_not_formattable<std::chrono::year_month_weekday, CharT>();
-  assert_is_not_formattable<std::chrono::year_month_weekday_last, CharT>();
+  assert_is_formattable<std::chrono::weekday_indexed, CharT>();
+  assert_is_formattable<std::chrono::weekday_last, CharT>();
+
+  assert_is_formattable<std::chrono::month_day, CharT>();
+  assert_is_formattable<std::chrono::month_day_last, CharT>();
+  assert_is_formattable<std::chrono::month_weekday, CharT>();
+  assert_is_formattable<std::chrono::month_weekday_last, CharT>();
+
+  assert_is_formattable<std::chrono::year_month, CharT>();
+  assert_is_formattable<std::chrono::year_month_day, CharT>();
+  assert_is_formattable<std::chrono::year_month_day_last, CharT>();
+  assert_is_formattable<std::chrono::year_month_weekday, CharT>();
+  assert_is_formattable<std::chrono::year_month_weekday_last, CharT>();
 
   assert_is_not_formattable<std::chrono::hh_mm_ss<std::chrono::microseconds>, CharT>();
 


        


More information about the libcxx-commits mailing list