diff --git a/stl/inc/chrono b/stl/inc/chrono index 262c3bd8dd6..c982303a40b 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -5454,6 +5454,12 @@ namespace chrono { switch (_Specs._Type) { case 'd': case 'e': + // Most months have a proper last day, but February depends on the year. + if constexpr (is_same_v<_Ty, month_day_last>) { + if (_Val.month() == February) { + _THROW(format_error("Cannot print the last day of February without a year")); + } + } if (_Has_modifier) { return false; } @@ -5546,6 +5552,7 @@ namespace chrono { _Month = static_cast(_Val.month()); } else if constexpr (is_same_v<_Ty, month_day_last>) { _Month = static_cast(_Val.month()); + _Day = static_cast(_Last_day_table[_Month - 1]); } else if constexpr (is_same_v<_Ty, year_month>) { _Month = static_cast(_Val.month()); _Year = static_cast(_Val.year()); @@ -5766,13 +5773,13 @@ struct _Chrono_formatter { _NODISCARD constexpr bool _Is_valid_type(const char _Type) noexcept { if constexpr (is_same_v<_Ty, _CHRONO day>) { return _Type == 'd' || _Type == 'e'; - } else if constexpr (_Is_any_of_v<_Ty, _CHRONO month, _CHRONO month_day_last>) { + } else if constexpr (is_same_v<_Ty, _CHRONO month>) { return _Type == 'b' || _Type == 'B' || _Type == 'h' || _Type == 'm'; } else if constexpr (is_same_v<_Ty, _CHRONO year>) { return _Type == 'Y' || _Type == 'y' || _Type == 'C'; } else if constexpr (is_same_v<_Ty, _CHRONO weekday>) { return _Type == 'a' || _Type == 'A' || _Type == 'u' || _Type == 'w'; - } else if constexpr (is_same_v<_Ty, _CHRONO month_day>) { + } else if constexpr (_Is_any_of_v<_Ty, _CHRONO month_day, _CHRONO month_day_last>) { return _Is_valid_type<_CHRONO month>(_Type) || _Is_valid_type<_CHRONO day>(_Type); } else if constexpr (is_same_v<_Ty, _CHRONO year_month>) { return _Is_valid_type<_CHRONO year>(_Type) || _Is_valid_type<_CHRONO month>(_Type); diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp index cb14051fd92..c591027dacf 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp @@ -411,7 +411,8 @@ void test_month_day_last_formatter() { stream_helper(STR("Feb/last"), February / last); assert(format(STR("{:%B}"), June / last) == STR("June")); - throw_helper(STR("{:%d}"), June / last); + assert(format(STR("{:%d}"), June / last) == STR("30")); + throw_helper(STR("{:%d}"), February / last); } template