30 #ifndef _GLIBCXX_CHRONO_IO_H
31 #define _GLIBCXX_CHRONO_IO_H 1
33 #pragma GCC system_header
35 #if __cplusplus >= 202002L
43 namespace std _GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
60 template<
typename _CharT>
62 _Widen(
const char* __narrow,
const wchar_t* __wide)
64 if constexpr (is_same_v<_CharT, wchar_t>)
69 #define _GLIBCXX_WIDEN_(C, S) ::std::chrono::__detail::_Widen<C>(S, L##S)
70 #define _GLIBCXX_WIDEN(S) _GLIBCXX_WIDEN_(_CharT, S)
72 template<
typename _Period,
typename _CharT>
74 __units_suffix() noexcept
79 #define _GLIBCXX_UNITS_SUFFIX(period, suffix) \
80 if constexpr (is_same_v<_Period, period>) \
81 return _GLIBCXX_WIDEN(suffix); \
84 _GLIBCXX_UNITS_SUFFIX(
atto,
"as")
85 _GLIBCXX_UNITS_SUFFIX(
femto,
"fs")
86 _GLIBCXX_UNITS_SUFFIX(
pico,
"ps")
87 _GLIBCXX_UNITS_SUFFIX(
nano,
"ns")
88 _GLIBCXX_UNITS_SUFFIX(
milli,
"ms")
89 #if _GLIBCXX_USE_ALT_MICROSECONDS_SUFFIX
92 _GLIBCXX_UNITS_SUFFIX(
micro,
"\u00b5s")
94 _GLIBCXX_UNITS_SUFFIX(
micro,
"us")
96 _GLIBCXX_UNITS_SUFFIX(
centi,
"cs")
97 _GLIBCXX_UNITS_SUFFIX(
deci,
"ds")
99 _GLIBCXX_UNITS_SUFFIX(
deca,
"das")
100 _GLIBCXX_UNITS_SUFFIX(
hecto,
"hs")
101 _GLIBCXX_UNITS_SUFFIX(
kilo,
"ks")
102 _GLIBCXX_UNITS_SUFFIX(
mega,
"Ms")
103 _GLIBCXX_UNITS_SUFFIX(
giga,
"Gs")
104 _GLIBCXX_UNITS_SUFFIX(
tera,
"Ts")
105 _GLIBCXX_UNITS_SUFFIX(
tera,
"Ts")
106 _GLIBCXX_UNITS_SUFFIX(
peta,
"Ps")
107 _GLIBCXX_UNITS_SUFFIX(
exa,
"Es")
111 #undef _GLIBCXX_UNITS_SUFFIX
115 template<
typename _Period,
typename _CharT,
typename _Out>
117 __fmt_units_suffix(_Out __out) noexcept
119 if (
auto __s = __detail::__units_suffix<_Period, _CharT>(); __s.size())
120 return __format::__write(
std::move(__out), __s);
121 else if constexpr (_Period::den == 1)
122 return std::format_to(
std::move(__out), _GLIBCXX_WIDEN(
"[{}]s"),
123 (uintmax_t)_Period::num);
125 return std::format_to(
std::move(__out), _GLIBCXX_WIDEN(
"[{}/{}]s"),
126 (uintmax_t)_Period::num,
127 (uintmax_t)_Period::den);
136 template<
typename _CharT,
typename _Traits,
137 typename _Rep,
typename _Period>
143 using period =
typename _Period::type;
145 __s.
flags(__os.flags());
146 __s.
imbue(__os.getloc());
149 __detail::__fmt_units_suffix<period, _CharT>(_Out(__s));
158 template<
typename _Duration>
159 struct __local_time_fmt
162 const string* _M_abbrev;
166 struct __local_fmt_t;
179 template<
typename _Duration>
180 inline __detail::__local_time_fmt<_Duration>
182 const string* __abbrev =
nullptr,
183 const seconds* __offset_sec =
nullptr)
184 {
return {__time, __abbrev, __offset_sec}; }
192 [[noreturn,__gnu__::__always_inline__]]
194 __no_timezone_available()
195 { __throw_format_error(
"format error: no timezone available for %Z or %z"); }
197 [[noreturn,__gnu__::__always_inline__]]
199 __not_valid_for_duration()
200 { __throw_format_error(
"format error: chrono-format-spec not valid for "
201 "chrono::duration"); }
203 [[noreturn,__gnu__::__always_inline__]]
205 __invalid_chrono_spec()
206 { __throw_format_error(
"format error: chrono-format-spec not valid for "
209 template<
typename _CharT>
210 struct _ChronoSpec : _Spec<_CharT>
212 basic_string_view<_CharT> _M_chrono_specs;
219 _Year = 1, _Month = 2, _Day = 4, _Weekday = 8, _TimeOfDay = 16,
221 _Date = _Year | _Month | _Day | _Weekday,
222 _DateTime = _Date | _TimeOfDay,
223 _ZonedDateTime = _DateTime | _TimeZone,
227 constexpr _ChronoParts
228 operator|(_ChronoParts __x, _ChronoParts __y)
229 {
return static_cast<_ChronoParts
>((int)__x | (
int)__y); }
232 template<
typename _CharT>
233 struct __formatter_chrono
235 using __string_view = basic_string_view<_CharT>;
236 using __string = basic_string<_CharT>;
238 template<
typename _ParseContext>
239 constexpr
typename _ParseContext::iterator
240 _M_parse(_ParseContext& __pc, _ChronoParts __parts)
242 auto __first = __pc.
begin();
243 auto __last = __pc.end();
245 _ChronoSpec<_CharT> __spec{};
247 auto __finalize = [
this, &__spec] {
251 auto __finished = [&] {
252 if (__first == __last || *__first ==
'}')
263 __first = __spec._M_parse_fill_and_align(__first, __last);
267 __first = __spec._M_parse_width(__first, __last, __pc);
271 if (__parts & _ChronoParts::_Duration)
273 __first = __spec._M_parse_precision(__first, __last, __pc);
278 __first = __spec._M_parse_locale(__first, __last);
285 __string_view __str(__first, __last - __first);
286 auto __end = __str.find(
'}');
287 if (__end != __str.npos)
289 __str.remove_suffix(__str.length() - __end);
290 __last = __first + __end;
292 if (__str.find(
'{') != __str.npos)
293 __throw_format_error(
"chrono format error: '{' in chrono-specs");
300 const auto __chrono_specs = __first++;
301 if (*__chrono_specs !=
'%')
302 __throw_format_error(
"chrono format error: no '%' at start of "
309 while (__first != __last)
311 enum _Mods { _Mod_none, _Mod_E, _Mod_O, _Mod_E_O };
312 _Mods __allowed_mods = _Mod_none;
314 _CharT __c = *__first++;
327 __needed = _DateTime;
328 __allowed_mods = _Mod_E;
332 __allowed_mods = _Mod_E;
337 __allowed_mods = _Mod_O;
349 __needed = _TimeOfDay;
350 __allowed_mods = _Mod_O;
353 if (!(__parts & _Duration))
358 __allowed_mods = _Mod_O;
361 __needed = _TimeOfDay;
362 __allowed_mods = _Mod_O;
368 __needed = _TimeOfDay;
372 __needed = _Duration;
375 __needed = _TimeOfDay;
376 __allowed_mods = _Mod_O;
381 __allowed_mods = _Mod_O;
387 __allowed_mods = _Mod_O;
391 __allowed_mods = _Mod_E;
394 __needed = _TimeOfDay;
395 __allowed_mods = _Mod_E;
399 __allowed_mods = _Mod_E_O;
403 __allowed_mods = _Mod_E;
406 __needed = _TimeZone;
407 __allowed_mods = _Mod_E_O;
410 __needed = _TimeZone;
418 if (__mod) [[unlikely]]
420 __allowed_mods = _Mod_none;
426 __throw_format_error(
"chrono format error: invalid "
427 " specifier in chrono-specs");
430 if ((__mod ==
'E' && !(__allowed_mods & _Mod_E))
431 || (__mod ==
'O' && !(__allowed_mods & _Mod_O)))
432 __throw_format_error(
"chrono format error: invalid "
433 " modifier in chrono-specs");
436 if ((__parts & __needed) != __needed)
437 __throw_format_error(
"chrono format error: format argument "
438 "does not contain the information "
439 "required by the chrono-specs");
442 size_t __pos = __string_view(__first, __last - __first).find(
'%');
447 if (__pos == __string_view::npos)
453 __first += __pos + 1;
458 if (__conv || __mod != _CharT())
459 __throw_format_error(
"chrono format error: unescaped '%' in "
463 _M_spec._M_chrono_specs
464 = __string_view(__chrono_specs, __first - __chrono_specs);
474 template<
typename _Tp,
typename _FormatContext>
475 typename _FormatContext::iterator
476 _M_format(
const _Tp& __t, _FormatContext& __fc,
477 bool __is_neg =
false)
const
479 auto __first = _M_spec._M_chrono_specs.begin();
480 const auto __last = _M_spec._M_chrono_specs.end();
481 if (__first == __last)
482 return _M_format_to_ostream(__t, __fc, __is_neg);
484 _Sink_iter<_CharT> __out;
485 __format::_Str_sink<_CharT> __sink;
486 bool __write_direct =
false;
487 if constexpr (is_same_v<
typename _FormatContext::iterator,
490 if (_M_spec._M_width_kind == __format::_WP_none)
493 __write_direct =
true;
496 __out = __sink.out();
499 __out = __sink.out();
503 if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>)
504 __is_neg = __t.is_negative();
506 auto __print_sign = [&__is_neg, &__out] {
507 if constexpr (chrono::__is_duration_v<_Tp>
508 || __is_specialization_of<_Tp, chrono::hh_mm_ss>)
511 *__out++ = _S_plus_minus[1];
518 constexpr
const _CharT* __literals = _GLIBCXX_WIDEN(
"\n\t%");
525 _CharT __c = *__first++;
530 __out = _M_a_A(__t,
std::move(__out), __fc, __c ==
'A');
535 __out = _M_b_B(__t,
std::move(__out), __fc, __c ==
'B');
538 __out = _M_c(__t,
std::move(__out), __fc, __mod ==
'E');
543 __out = _M_C_y_Y(__t,
std::move(__out), __fc, __c, __mod);
547 __out = _M_d_e(__t,
std::move(__out), __fc, __c, __mod ==
'O');
550 __out = _M_D(__t,
std::move(__out), __fc);
553 __out = _M_F(__t,
std::move(__out), __fc);
557 __out = _M_g_G(__t,
std::move(__out), __fc, __c ==
'G');
561 __out = _M_H_I(__t, __print_sign(), __fc, __c, __mod ==
'O');
564 __out = _M_j(__t, __print_sign(), __fc);
567 __out = _M_m(__t,
std::move(__out), __fc, __mod ==
'O');
570 __out = _M_M(__t, __print_sign(), __fc, __mod ==
'O');
573 __out = _M_p(__t,
std::move(__out), __fc);
576 __out = _M_q(__t,
std::move(__out), __fc);
580 if constexpr (chrono::__is_duration_v<_Tp>)
581 __out = std::format_to(__print_sign(), _S_empty_spec,
584 __throw_format_error(
"chrono format error: argument is "
588 __out = _M_r(__t, __print_sign(), __fc);
592 __out = _M_R_T(__t, __print_sign(), __fc, __c ==
'T');
595 __out = _M_S(__t, __print_sign(), __fc, __mod ==
'O');
599 __out = _M_u_w(__t,
std::move(__out), __fc, __c, __mod ==
'O');
604 __out = _M_U_V_W(__t,
std::move(__out), __fc, __c,
608 __out = _M_x(__t,
std::move(__out), __fc, __mod ==
'E');
611 __out = _M_X(__t, __print_sign(), __fc, __mod ==
'E');
614 __out = _M_z(__t,
std::move(__out), __fc, (
bool)__mod);
617 __out = _M_Z(__t,
std::move(__out), __fc);
620 *__out++ = __literals[0];
623 *__out++ = __literals[1];
626 *__out++ = __literals[2];
638 __string_view __str(__first, __last - __first);
639 size_t __pos = __str.find(
'%');
644 if (__pos == __str.npos)
648 __str.remove_suffix(__str.length() - __pos);
649 __first += __pos + 1;
651 __out = __format::__write(
std::move(__out), __str);
654 while (__first != __last);
656 if constexpr (is_same_v<
typename _FormatContext::iterator,
661 auto __str =
std::
move(__sink).get();
662 return __format::__write_padded_as_spec(__str, __str.
size(),
666 _ChronoSpec<_CharT> _M_spec;
670 template<typename _FormatContext>
672 _M_locale(_FormatContext& __fc)
const
674 if (!_M_spec._M_localized)
677 return __fc.locale();
685 template<
typename _Tp,
typename _FormatContext>
686 typename _FormatContext::iterator
687 _M_format_to_ostream(
const _Tp& __t, _FormatContext& __fc,
690 using ::std::chrono::__detail::__utc_leap_second;
691 using ::std::chrono::__detail::__local_time_fmt;
693 if constexpr (__is_specialization_of<_Tp, __local_time_fmt>)
694 return _M_format_to_ostream(__t._M_time, __fc,
false);
697 basic_ostringstream<_CharT> __os;
698 __os.imbue(_M_locale(__fc));
700 if constexpr (__is_specialization_of<_Tp, __utc_leap_second>)
701 __os << __t._M_date <<
' ' << __t._M_time;
702 else if constexpr (chrono::__is_time_point_v<_Tp>)
709 if constexpr (is_convertible_v<_Tp, chrono::sys_days>)
710 __os << _S_date(__t);
713 auto __days = chrono::floor<chrono::days>(__t);
714 __os << chrono::year_month_day(__days) <<
' '
715 << chrono::hh_mm_ss(__t - __days);
720 if constexpr (chrono::__is_duration_v<_Tp>)
721 if (__is_neg) [[unlikely]]
722 __os << _S_plus_minus[1];
727 return __format::__write_padded_as_spec(__str, __str.size(),
732 static constexpr
const _CharT* _S_chars
733 = _GLIBCXX_WIDEN(
"0123456789+-:/ {}");
734 static constexpr
const _CharT* _S_plus_minus = _S_chars + 10;
735 static constexpr _CharT _S_colon = _S_chars[12];
736 static constexpr _CharT _S_slash = _S_chars[13];
737 static constexpr _CharT _S_space = _S_chars[14];
738 static constexpr
const _CharT* _S_empty_spec = _S_chars + 15;
740 template<
typename _Tp,
typename _FormatContext>
741 typename _FormatContext::iterator
742 _M_a_A(
const _Tp& __t,
typename _FormatContext::iterator __out,
743 _FormatContext& __ctx,
bool __full)
const
747 chrono::weekday __wd = _S_weekday(__t);
749 __throw_format_error(
"format error: invalid weekday");
751 locale __loc = _M_locale(__ctx);
752 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
753 const _CharT* __days[7];
755 __tp._M_days(__days);
757 __tp._M_days_abbreviated(__days);
758 __string_view __str(__days[__wd.c_encoding()]);
759 return __format::__write(
std::move(__out), __str);
762 template<
typename _Tp,
typename _FormatContext>
763 typename _FormatContext::iterator
764 _M_b_B(
const _Tp& __t,
typename _FormatContext::iterator __out,
765 _FormatContext& __ctx,
bool __full)
const
769 chrono::month __m = _S_month(__t);
771 __throw_format_error(
"format error: invalid month");
772 locale __loc = _M_locale(__ctx);
773 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
774 const _CharT* __months[12];
776 __tp._M_months(__months);
778 __tp._M_months_abbreviated(__months);
779 __string_view __str(__months[(
unsigned)__m - 1]);
780 return __format::__write(
std::move(__out), __str);
783 template<
typename _Tp,
typename _FormatContext>
784 typename _FormatContext::iterator
785 _M_c(
const _Tp& __tt,
typename _FormatContext::iterator __out,
786 _FormatContext& __ctx,
bool __mod =
false)
const
791 basic_string<_CharT> __fmt;
792 auto __t = _S_floor_seconds(__tt);
793 locale __loc = _M_locale(__ctx);
794 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
795 const _CharT* __formats[2];
796 __tp._M_date_time_formats(__formats);
797 if (*__formats[__mod]) [[likely]]
799 __fmt = _GLIBCXX_WIDEN(
"{:L}");
800 __fmt.insert(3u, __formats[__mod]);
803 __fmt = _GLIBCXX_WIDEN(
"{:L%a %b %e %T %Y}");
804 return std::vformat_to(
std::move(__out), __loc, __fmt,
805 std::make_format_args<_FormatContext>(__t));
808 template<
typename _Tp,
typename _FormatContext>
809 typename _FormatContext::iterator
810 _M_C_y_Y(
const _Tp& __t,
typename _FormatContext::iterator __out,
811 _FormatContext& __ctx, _CharT __conv, _CharT __mod = 0)
const
821 chrono::year __y = _S_year(__t);
823 if (__mod) [[unlikely]]
826 __tm.tm_year = (int)__y - 1900;
827 return _M_locale_fmt(
std::move(__out), _M_locale(__ctx), __tm,
831 basic_string<_CharT> __s;
833 const bool __is_neg = __yi < 0;
834 __yi = __builtin_abs(__yi);
836 if (__conv ==
'Y' || __conv ==
'C')
838 int __ci = __yi / 100;
839 if (__is_neg) [[unlikely]]
841 __s.assign(1, _S_plus_minus[1]);
843 if (__conv ==
'C' && (__ci * 100) != __yi)
846 if (__ci >= 100) [[unlikely]]
848 __s += std::format(_S_empty_spec, __ci / 100);
851 __s += _S_two_digits(__ci);
854 if (__conv ==
'Y' || __conv ==
'y')
855 __s += _S_two_digits(__yi % 100);
857 return __format::__write(
std::move(__out), __string_view(__s));
860 template<
typename _Tp,
typename _FormatContext>
861 typename _FormatContext::iterator
862 _M_D(
const _Tp& __t,
typename _FormatContext::iterator __out,
863 _FormatContext&)
const
865 auto __ymd = _S_date(__t);
866 basic_string<_CharT> __s;
867 #if ! _GLIBCXX_USE_CXX11_ABI
870 __s = _S_two_digits((
unsigned)__ymd.month());
872 __s += _S_two_digits((
unsigned)__ymd.day());
874 __s += _S_two_digits(__builtin_abs((
int)__ymd.year()) % 100);
875 return __format::__write(
std::move(__out), __string_view(__s));
878 template<
typename _Tp,
typename _FormatContext>
879 typename _FormatContext::iterator
880 _M_d_e(
const _Tp& __t,
typename _FormatContext::iterator __out,
881 _FormatContext& __ctx, _CharT __conv,
bool __mod =
false)
const
888 chrono::day __d = _S_day(__t);
889 unsigned __i = (unsigned)__d;
891 if (__mod) [[unlikely]]
895 return _M_locale_fmt(
std::move(__out), _M_locale(__ctx), __tm,
899 auto __sv = _S_two_digits(__i);
901 if (__conv == _CharT(
'e') && __i < 10)
907 return __format::__write(
std::move(__out), __sv);
910 template<
typename _Tp,
typename _FormatContext>
911 typename _FormatContext::iterator
912 _M_F(
const _Tp& __t,
typename _FormatContext::iterator __out,
913 _FormatContext&)
const
915 auto __ymd = _S_date(__t);
916 basic_string<_CharT> __s;
917 #if ! _GLIBCXX_USE_CXX11_ABI
920 __s += std::format(_GLIBCXX_WIDEN(
"{:04d}- - "), (
int)__ymd.year());
921 auto __sv = _S_two_digits((
unsigned)__ymd.month());
922 __s[__s.size() - 5] = __sv[0];
923 __s[__s.size() - 4] = __sv[1];
924 __sv = _S_two_digits((
unsigned)__ymd.day());
925 __s[__s.size() - 2] = __sv[0];
926 __s[__s.size() - 1] = __sv[1];
928 return __format::__write(
std::move(__out), __sv);
931 template<
typename _Tp,
typename _FormatContext>
932 typename _FormatContext::iterator
933 _M_g_G(
const _Tp& __t,
typename _FormatContext::iterator __out,
934 _FormatContext& __ctx,
bool __full)
const
938 using namespace chrono;
939 auto __d = _S_days(__t);
941 __d -= (weekday(__d) - Monday) -
days(3);
943 year __y = year_month_day(__d).year();
944 return _M_C_y_Y(__y,
std::move(__out), __ctx,
"yY"[__full]);
947 template<
typename _Tp,
typename _FormatContext>
948 typename _FormatContext::iterator
949 _M_H_I(
const _Tp& __t,
typename _FormatContext::iterator __out,
950 _FormatContext& __ctx, _CharT __conv,
bool __mod =
false)
const
957 const auto __hms = _S_hms(__t);
958 int __i = __hms.hours().count();
960 if (__mod) [[unlikely]]
964 return _M_locale_fmt(
std::move(__out), _M_locale(__ctx), __tm,
968 if (__conv == _CharT(
'I'))
975 return __format::__write(
std::move(__out), _S_two_digits(__i));
978 template<
typename _Tp,
typename _FormatContext>
979 typename _FormatContext::iterator
980 _M_j(
const _Tp& __t,
typename _FormatContext::iterator __out,
981 _FormatContext&)
const
983 if constexpr (chrono::__is_duration_v<_Tp>)
986 unsigned __d = chrono::duration_cast<chrono::days>(__t).count();
987 return std::format_to(
std::move(__out), _S_empty_spec, __d);
992 using namespace chrono;
993 auto __day = _S_days(__t);
994 auto __ymd = _S_date(__t);
998 if constexpr (is_same_v<
typename decltype(__day)::clock, local_t>)
999 __d = __day - local_days(__ymd.year()/January/0);
1001 __d = __day - sys_days(__ymd.year()/January/0);
1002 return
std::format_to(
std::
move(__out), _GLIBCXX_WIDEN("{:03d}
"),
1007 template<typename _Tp, typename _FormatContext>
1008 typename _FormatContext::iterator
1009 _M_m(const _Tp& __t, typename _FormatContext::iterator __out,
1010 _FormatContext& __ctx, bool __mod) const
1012 // %m month as a decimal number.
1013 // %Om Locale's alternative representation.
1015 auto __m = _S_month(__t);
1016 auto __i = (unsigned)__m;
1018 if (__mod) [[unlikely]] // %Om
1021 __tm.tm_mon = __i - 1;
1022 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm,
1026 return __format::__write(std::move(__out), _S_two_digits(__i));
1029 template<typename _Tp, typename _FormatContext>
1030 typename _FormatContext::iterator
1031 _M_M(const _Tp& __t, typename _FormatContext::iterator __out,
1032 _FormatContext& __ctx, bool __mod) const
1034 // %M The minute as a decimal number.
1035 // %OM Locale's alternative representation.
1037 auto __m = _S_hms(__t).minutes();
1038 auto __i = __m.count();
1040 if (__mod) [[unlikely]] // %OM
1044 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm,
1048 return __format::__write(std::move(__out), _S_two_digits(__i));
1051 template<typename _Tp, typename _FormatContext>
1052 typename _FormatContext::iterator
1053 _M_p(const _Tp& __t, typename _FormatContext::iterator __out,
1054 _FormatContext& __ctx) const
1056 // %p The locale's equivalent of the AM/PM designations.
1057 auto __hms = _S_hms(__t);
1058 locale __loc = _M_locale(__ctx);
1059 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
1060 const _CharT* __ampm[2];
1061 __tp._M_am_pm(__ampm);
1062 return std::format_to(std::move(__out), _S_empty_spec,
1063 __ampm[__hms.hours().count() >= 12]);
1066 template<typename _Tp, typename _FormatContext>
1067 typename _FormatContext::iterator
1068 _M_q(const _Tp&, typename _FormatContext::iterator __out,
1069 _FormatContext&) const
1071 // %q The duration's unit suffix
1072 if constexpr (!chrono::__is_duration_v<_Tp>)
1073 __throw_format_error("format error: argument is not a duration
");
1076 namespace __d = chrono::__detail;
1077 using period = typename _Tp::period;
1078 return __d::__fmt_units_suffix<period, _CharT>(std::move(__out));
1082 // %Q handled in _M_format
1084 template<typename _Tp, typename _FormatContext>
1085 typename _FormatContext::iterator
1086 _M_r(const _Tp& __tt, typename _FormatContext::iterator __out,
1087 _FormatContext& __ctx) const
1089 // %r locale's 12-hour clock time.
1090 auto __t = _S_floor_seconds(__tt);
1091 locale __loc = _M_locale(__ctx);
1092 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
1093 const _CharT* __ampm_fmt;
1094 __tp._M_am_pm_format(&__ampm_fmt);
1095 basic_string<_CharT> __fmt(_S_empty_spec);
1096 __fmt.insert(1u, 1u, _S_colon);
1097 __fmt.insert(2u, __ampm_fmt);
1098 return std::vformat_to(std::move(__out), __fmt,
1099 std::make_format_args<_FormatContext>(__t));
1102 template<typename _Tp, typename _FormatContext>
1103 typename _FormatContext::iterator
1104 _M_R_T(const _Tp& __t, typename _FormatContext::iterator __out,
1105 _FormatContext& __ctx, bool __secs) const
1107 // %R Equivalent to %H:%M
1108 // %T Equivalent to %H:%M:%S
1109 auto __hms = _S_hms(__t);
1111 basic_string<_CharT> __s;
1112 #if ! _GLIBCXX_USE_CXX11_ABI
1115 __s = std::format(_GLIBCXX_WIDEN("{:02d}:00
"), __hms.hours().count());
1116 auto __sv = _S_two_digits(__hms.minutes().count());
1117 __s[__s.size() - 2] = __sv[0];
1118 __s[__s.size() - 1] = __sv[1];
1120 __out = __format::__write(std::move(__out), __sv);
1123 *__out++ = _S_colon;
1124 __out = _M_S(__hms, std::move(__out), __ctx);
1129 template<typename _Tp, typename _FormatContext>
1130 typename _FormatContext::iterator
1131 _M_S(const _Tp& __t, typename _FormatContext::iterator __out,
1132 _FormatContext& __ctx, bool __mod = false) const
1134 // %S Seconds as a decimal number.
1135 // %OS The locale's alternative representation.
1136 auto __hms = _S_hms(__t);
1138 if (__mod) [[unlikely]] // %OS
1141 __tm.tm_sec = (int)__hms.seconds().count();
1142 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm,
1146 if constexpr (__hms.fractional_width == 0)
1147 __out = __format::__write(std::move(__out),
1148 _S_two_digits(__hms.seconds().count()));
1151 locale __loc = _M_locale(__ctx);
1152 auto __s = __hms.seconds();
1153 auto __ss = __hms.subseconds();
1154 using rep = typename decltype(__ss)::rep;
1155 if constexpr (is_floating_point_v<rep>)
1157 chrono::duration<rep> __fs = __s + __ss;
1158 __out = std::format_to(std::move(__out), __loc,
1159 _GLIBCXX_WIDEN("{:#0{}.{}Lf}
"),
1161 3 + __hms.fractional_width,
1162 __hms.fractional_width);
1167 = use_facet<numpunct<_CharT>>(__loc);
1168 __out = __format::__write(std::move(__out),
1169 _S_two_digits(__s.count()));
1170 *__out++ = __np.decimal_point();
1171 if constexpr (is_integral_v<rep>)
1172 __out = std::format_to(std::move(__out),
1173 _GLIBCXX_WIDEN("{:0{}}
"),
1175 __hms.fractional_width);
1178 auto __str = std::format(_S_empty_spec, __ss.count());
1179 __out = std::format_to(_GLIBCXX_WIDEN("{:0>{}s}
"),
1181 __hms.fractional_width);
1188 // %t handled in _M_format
1190 template<typename _Tp, typename _FormatContext>
1191 typename _FormatContext::iterator
1192 _M_u_w(const _Tp& __t, typename _FormatContext::iterator __out,
1193 _FormatContext& __ctx, _CharT __conv, bool __mod = false) const
1195 // %u ISO weekday as a decimal number (1-7), where Monday is 1.
1196 // %Ou Locale's alternative numeric rep.
1197 // %w Weekday as a decimal number (0-6), where Sunday is 0.
1198 // %Ow Locale's alternative numeric rep.
1200 chrono::weekday __wd = _S_weekday(__t);
1202 if (__mod) [[unlikely]]
1205 __tm.tm_wday = __wd.c_encoding();
1206 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm,
1210 unsigned __wdi = __conv == 'u' ? __wd.iso_encoding()
1211 : __wd.c_encoding();
1212 const _CharT __d = _S_digit(__wdi);
1213 return __format::__write(std::move(__out), __string_view(&__d, 1));
1216 template<typename _Tp, typename _FormatContext>
1217 typename _FormatContext::iterator
1218 _M_U_V_W(const _Tp& __t, typename _FormatContext::iterator __out,
1219 _FormatContext& __ctx, _CharT __conv, bool __mod = false) const
1221 // %U Week number of the year as a decimal number, from first Sunday.
1222 // %OU Locale's alternative numeric rep.
1223 // %V ISO week-based week number as a decimal number.
1224 // %OV Locale's alternative numeric rep.
1225 // %W Week number of the year as a decimal number, from first Monday.
1226 // %OW Locale's alternative numeric rep.
1227 using namespace chrono;
1228 auto __d = _S_days(__t);
1229 using _TDays = decltype(__d); // Either sys_days or local_days.
1231 if (__mod) [[unlikely]]
1233 const year_month_day __ymd(__d);
1234 const year __y = __ymd.year();
1236 __tm.tm_year = (int)__y - 1900;
1237 __tm.tm_yday = (__d - _TDays(__y/January/1)).count();
1238 __tm.tm_wday = weekday(__d).c_encoding();
1239 return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm,
1243 _TDays __first; // First day of week 1.
1244 if (__conv == 'V') // W01 begins on Monday before first Thursday.
1246 // Move to nearest Thursday:
1247 __d -= (weekday(__d) - Monday) - days(3);
1248 // ISO week of __t is number of weeks since January 1 of the
1249 // same year as that nearest Thursday.
1250 __first = _TDays(year_month_day(__d).year()/January/1);
1255 if constexpr (requires { __t.year(); })
1258 __y = year_month_day(__d).year();
1259 const weekday __weekstart = __conv == 'U' ? Sunday : Monday;
1260 __first = _TDays(__y/January/__weekstart[1]);
1262 auto __weeks = chrono::floor<weeks>(__d - __first);
1263 __string_view __sv = _S_two_digits(__weeks.count() + 1);
1264 return __format::__write(std::move(__out), __sv);
1267 template<typename _Tp, typename _FormatContext>
1268 typename _FormatContext::iterator
1269 _M_x(const _Tp& __t, typename _FormatContext::iterator __out,
1270 _FormatContext& __ctx, bool __mod = false) const
1272 // %x Locale's date rep
1273 // %Ex Locale's alternative date representation.
1274 locale __loc = _M_locale(__ctx);
1275 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
1276 const _CharT* __date_reps[2];
1277 __tp._M_date_formats(__date_reps);
1278 const _CharT* __rep = __date_reps[__mod];
1280 return _M_D(__t, std::move(__out), __ctx);
1282 basic_string<_CharT> __fmt(_S_empty_spec);
1283 __fmt.insert(1u, 1u, _S_colon);
1284 __fmt.insert(2u, __rep);
1285 return std::vformat_to(std::move(__out), __fmt,
1286 std::make_format_args<_FormatContext>(__t));
1289 template<typename _Tp, typename _FormatContext>
1290 typename _FormatContext::iterator
1291 _M_X(const _Tp& __tt, typename _FormatContext::iterator __out,
1292 _FormatContext& __ctx, bool __mod = false) const
1294 // %X Locale's time rep
1295 // %EX Locale's alternative time representation.
1296 auto __t = _S_floor_seconds(__tt);
1297 locale __loc = _M_locale(__ctx);
1298 const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
1299 const _CharT* __time_reps[2];
1300 __tp._M_time_formats(__time_reps);
1301 const _CharT* __rep = __time_reps[__mod];
1303 return _M_R_T(__t, std::move(__out), __ctx, true);
1305 basic_string<_CharT> __fmt(_S_empty_spec);
1306 __fmt.insert(1u, 1u, _S_colon);
1307 __fmt.insert(2u, __rep);
1308 return std::vformat_to(std::move(__out), __fmt,
1309 std::make_format_args<_FormatContext>(__t));
1312 template<typename _Tp, typename _FormatContext>
1313 typename _FormatContext::iterator
1314 _M_z(const _Tp& __t, typename _FormatContext::iterator __out,
1315 _FormatContext&, bool __mod = false) const
1317 using ::std::chrono::__detail::__utc_leap_second;
1318 using ::std::chrono::__detail::__local_time_fmt;
1320 auto __utc = __mod ? __string_view(_GLIBCXX_WIDEN("+00:00
"), 6)
1321 : __string_view(_GLIBCXX_WIDEN("+0000
"), 5);
1323 if constexpr (chrono::__is_time_point_v<_Tp>)
1325 if constexpr (is_same_v<typename _Tp::clock,
1326 chrono::system_clock>)
1327 return __format::__write(std::move(__out), __utc);
1329 else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>)
1331 if (__t._M_offset_sec)
1334 basic_string<_CharT> __s;
1335 if (*__t._M_offset_sec != 0s)
1337 chrono:: hh_mm_ss __hms(*__t._M_offset_sec);
1338 __s = _S_plus_minus[__hms.is_negative()];
1339 __s += _S_two_digits(__hms.hours().count());
1342 __s += _S_two_digits(__hms.minutes().count());
1345 return __format::__write(std::move(__out), __sv);
1348 else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>)
1349 return __format::__write(std::move(__out), __utc);
1351 __no_timezone_available();
1354 template<typename _Tp, typename _FormatContext>
1355 typename _FormatContext::iterator
1356 _M_Z(const _Tp& __t, typename _FormatContext::iterator __out,
1357 _FormatContext& __ctx) const
1359 using ::std::chrono::__detail::__utc_leap_second;
1360 using ::std::chrono::__detail::__local_time_fmt;
1362 __string_view __utc(_GLIBCXX_WIDEN("UTC
"), 3);
1363 if constexpr (chrono::__is_time_point_v<_Tp>)
1365 if constexpr (is_same_v<typename _Tp::clock,
1366 chrono::system_clock>)
1367 return __format::__write(std::move(__out), __utc);
1369 else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>)
1373 string_view __sv = *__t._M_abbrev;
1374 if constexpr (is_same_v<_CharT, char>)
1375 return __format::__write(std::move(__out), __sv);
1378 // TODO use resize_and_overwrite
1379 basic_string<_CharT> __ws(__sv.size(), _CharT());
1380 auto& __ct = use_facet<ctype<_CharT>>(_M_locale(__ctx));
1381 __ct.widen(__sv.begin(), __sv.end(), __ws.data());
1382 __string_view __wsv = __ws;
1383 return __format::__write(std::move(__out), __wsv);
1387 else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>)
1388 return __format::__write(std::move(__out), __utc);
1390 __no_timezone_available();
1393 // %% handled in _M_format
1395 // A single digit character in the range '0'..'9'.
1397 _S_digit(int __n) noexcept
1399 // Extra 9s avoid past-the-end read on bad input.
1400 return _GLIBCXX_WIDEN("0123456789999999
")[__n & 0xf];
1403 // A string view of two digit characters, "00
".."99
".
1404 static basic_string_view<_CharT>
1405 _S_two_digits(int __n) noexcept
1408 _GLIBCXX_WIDEN("0001020304050607080910111213141516171819
"
1409 "2021222324252627282930313233343536373839
"
1410 "4041424344454647484950515253545556575859
"
1411 "6061626364656667686970717273747576777879
"
1412 "8081828384858687888990919293949596979899
"
1413 "9999999999999999999999999999999999999999
"
1414 "9999999999999999
") + 2 * (__n & 0x7f),
1419 // Accessors for the components of chrono types:
1421 // Returns a hh_mm_ss.
1422 template<typename _Tp>
1423 static decltype(auto)
1424 _S_hms(const _Tp& __t)
1426 using ::std::chrono::__detail::__utc_leap_second;
1427 using ::std::chrono::__detail::__local_time_fmt;
1429 if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>)
1431 else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>)
1433 else if constexpr (chrono::__is_duration_v<_Tp>)
1434 return chrono::hh_mm_ss<_Tp>(__t);
1435 else if constexpr (chrono::__is_time_point_v<_Tp>)
1436 return chrono::hh_mm_ss(__t - chrono::floor<chrono::days>(__t));
1437 else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>)
1438 return _S_hms(__t._M_time);
1441 __invalid_chrono_spec();
1442 return chrono::hh_mm_ss<chrono::seconds>();
1446 // Returns a sys_days or local_days.
1447 template<typename _Tp>
1449 _S_days(const _Tp& __t)
1451 using namespace chrono;
1452 using ::std::chrono::__detail::__utc_leap_second;
1453 using ::std::chrono::__detail::__local_time_fmt;
1455 if constexpr (__is_time_point_v<_Tp>)
1456 return chrono::floor<days>(__t);
1457 else if constexpr (__is_specialization_of<_Tp, __utc_leap_second>)
1459 else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>)
1460 return chrono::floor<days>(__t._M_time);
1461 else if constexpr (is_same_v<_Tp, year_month_day>
1462 || is_same_v<_Tp, year_month_day_last>
1463 || is_same_v<_Tp, year_month_weekday>
1464 || is_same_v<_Tp, year_month_weekday_last>)
1465 return sys_days(__t);
1468 if constexpr (__is_duration_v<_Tp>)
1469 __not_valid_for_duration();
1471 __invalid_chrono_spec();
1472 return chrono::sys_days();
1476 // Returns a year_month_day.
1477 template<typename _Tp>
1478 static chrono::year_month_day
1479 _S_date(const _Tp& __t)
1481 if constexpr (is_same_v<_Tp, chrono::year_month_day>)
1484 return chrono::year_month_day(_S_days(__t));
1487 template<typename _Tp>
1489 _S_day(const _Tp& __t)
1491 using namespace chrono;
1493 if constexpr (is_same_v<_Tp, day>)
1495 else if constexpr (requires { __t.day(); })
1498 return _S_date(__t).day();
1501 template<typename _Tp>
1502 static chrono::month
1503 _S_month(const _Tp& __t)
1505 using namespace chrono;
1507 if constexpr (is_same_v<_Tp, month>)
1509 else if constexpr (requires { __t.month(); })
1512 return _S_date(__t).month();
1515 template<typename _Tp>
1517 _S_year(const _Tp& __t)
1519 using namespace chrono;
1521 if constexpr (is_same_v<_Tp, year>)
1523 else if constexpr (requires { __t.year(); })
1526 return _S_date(__t).year();
1529 template<typename _Tp>
1530 static chrono::weekday
1531 _S_weekday(const _Tp& __t)
1533 using namespace ::std::chrono;
1534 using ::std::chrono::__detail::__local_time_fmt;
1536 if constexpr (is_same_v<_Tp, weekday>)
1538 else if constexpr (requires { __t.weekday(); })
1539 return __t.weekday();
1540 else if constexpr (is_same_v<_Tp, month_weekday>)
1541 return __t.weekday_indexed().weekday();
1542 else if constexpr (is_same_v<_Tp, month_weekday_last>)
1543 return __t.weekday_last().weekday();
1545 return weekday(_S_days(__t));
1548 // Remove subsecond precision from a time_point.
1549 template<typename _Tp>
1551 _S_floor_seconds(const _Tp& __t)
1553 using chrono::__detail::__local_time_fmt;
1554 if constexpr (chrono::__is_time_point_v<_Tp>
1555 || chrono::__is_duration_v<_Tp>)
1557 if constexpr (_Tp::period::den != 1)
1558 return chrono::floor<chrono::seconds>(__t);
1562 else if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>)
1564 if constexpr (_Tp::fractional_width != 0)
1565 return chrono::floor<chrono::seconds>(__t.to_duration());
1569 else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>)
1570 return _S_floor_seconds(__t._M_time);
1575 // Use the formatting locale's std::time_put facet to produce
1576 // a locale-specific representation.
1577 template<typename _Iter>
1579 _M_locale_fmt(_Iter __out, const locale& __loc, const struct tm& __tm,
1580 char __fmt, char __mod) const
1582 basic_ostringstream<_CharT> __os;
1583 const auto& __tp = use_facet<time_put<_CharT>>(__loc);
1584 __tp.put(__os, __os, _S_space, &__tm, __fmt, __mod);
1586 __out = __format::__write(std::move(__out), __os.view());
1591 } // namespace __format
1594 template<typename _Rep, typename _Period, typename _CharT>
1595 struct formatter<chrono::duration<_Rep, _Period>, _CharT>
1597 constexpr typename basic_format_parse_context<_CharT>::iterator
1598 parse(basic_format_parse_context<_CharT>& __pc)
1600 using namespace __format;
1601 auto __it = _M_f._M_parse(__pc, _Duration|_TimeOfDay);
1602 if constexpr (!is_floating_point_v<_Rep>)
1603 if (_M_f._M_spec._M_prec_kind != __format::_WP_none)
1604 __throw_format_error("format error: invalid precision
for duration
");
1608 template<typename _Out>
1609 typename basic_format_context<_Out, _CharT>::iterator
1610 format(const chrono::duration<_Rep, _Period>& __d,
1611 basic_format_context<_Out, _CharT>& __fc) const
1613 if constexpr (numeric_limits<_Rep>::is_signed)
1614 if (__d < __d.zero()) [[unlikely]]
1616 if constexpr (is_integral_v<_Rep>)
1618 // -d is undefined for the most negative integer.
1619 // Convert duration to corresponding unsigned rep.
1620 using _URep = make_unsigned_t<_Rep>;
1621 auto __ucnt = -static_cast<_URep>(__d.count());
1622 auto __ud = chrono::duration<_URep, _Period>(__ucnt);
1623 return _M_f._M_format(__ud, __fc, true);
1626 return _M_f._M_format(-__d, __fc, true);
1628 return _M_f._M_format(__d, __fc, false);
1632 __format::__formatter_chrono<_CharT> _M_f;
1635 template<typename _CharT>
1636 struct formatter<chrono::day, _CharT>
1638 template<typename _ParseContext>
1639 constexpr typename _ParseContext::iterator
1640 parse(_ParseContext& __pc)
1641 { return _M_f._M_parse(__pc, __format::_Day); }
1643 template<typename _FormatContext>
1644 typename _FormatContext::iterator
1645 format(const chrono::day& __t, _FormatContext& __fc) const
1646 { return _M_f._M_format(__t, __fc); }
1649 __format::__formatter_chrono<_CharT> _M_f;
1652 template<typename _CharT>
1653 struct formatter<chrono::month, _CharT>
1655 template<typename _ParseContext>
1656 constexpr typename _ParseContext::iterator
1657 parse(_ParseContext& __pc)
1658 { return _M_f._M_parse(__pc, __format::_Month); }
1660 template<typename _FormatContext>
1661 typename _FormatContext::iterator
1662 format(const chrono::month& __t, _FormatContext& __fc) const
1663 { return _M_f._M_format(__t, __fc); }
1666 __format::__formatter_chrono<_CharT> _M_f;
1669 template<typename _CharT>
1670 struct formatter<chrono::year, _CharT>
1672 template<typename _ParseContext>
1673 constexpr typename _ParseContext::iterator
1674 parse(_ParseContext& __pc)
1675 { return _M_f._M_parse(__pc, __format::_Year); }
1677 template<typename _FormatContext>
1678 typename _FormatContext::iterator
1679 format(const chrono::year& __t, _FormatContext& __fc) const
1680 { return _M_f._M_format(__t, __fc); }
1683 __format::__formatter_chrono<_CharT> _M_f;
1686 template<typename _CharT>
1687 struct formatter<chrono::weekday, _CharT>
1689 template<typename _ParseContext>
1690 constexpr typename _ParseContext::iterator
1691 parse(_ParseContext& __pc)
1692 { return _M_f._M_parse(__pc, __format::_Weekday); }
1694 template<typename _FormatContext>
1695 typename _FormatContext::iterator
1696 format(const chrono::weekday& __t, _FormatContext& __fc) const
1697 { return _M_f._M_format(__t, __fc); }
1700 __format::__formatter_chrono<_CharT> _M_f;
1703 template<typename _CharT>
1704 struct formatter<chrono::weekday_indexed, _CharT>
1706 template<typename _ParseContext>
1707 constexpr typename _ParseContext::iterator
1708 parse(_ParseContext& __pc)
1709 { return _M_f._M_parse(__pc, __format::_Weekday); }
1711 template<typename _FormatContext>
1712 typename _FormatContext::iterator
1713 format(const chrono::weekday_indexed& __t, _FormatContext& __fc) const
1714 { return _M_f._M_format(__t, __fc); }
1717 __format::__formatter_chrono<_CharT> _M_f;
1720 template<typename _CharT>
1721 struct formatter<chrono::weekday_last, _CharT>
1723 template<typename _ParseContext>
1724 constexpr typename _ParseContext::iterator
1725 parse(_ParseContext& __pc)
1726 { return _M_f._M_parse(__pc, __format::_Weekday); }
1728 template<typename _FormatContext>
1729 typename _FormatContext::iterator
1730 format(const chrono::weekday_last& __t, _FormatContext& __fc) const
1731 { return _M_f._M_format(__t, __fc); }
1734 __format::__formatter_chrono<_CharT> _M_f;
1737 template<typename _CharT>
1738 struct formatter<chrono::month_day, _CharT>
1740 template<typename _ParseContext>
1741 constexpr typename _ParseContext::iterator
1742 parse(_ParseContext& __pc)
1743 { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); }
1745 template<typename _FormatContext>
1746 typename _FormatContext::iterator
1747 format(const chrono::month_day& __t, _FormatContext& __fc) const
1748 { return _M_f._M_format(__t, __fc); }
1751 __format::__formatter_chrono<_CharT> _M_f;
1754 template<typename _CharT>
1755 struct formatter<chrono::month_day_last, _CharT>
1757 template<typename _ParseContext>
1758 constexpr typename _ParseContext::iterator
1759 parse(_ParseContext& __pc)
1760 { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); }
1762 template<typename _FormatContext>
1763 typename _FormatContext::iterator
1764 format(const chrono::month_day_last& __t, _FormatContext& __fc) const
1765 { return _M_f._M_format(__t, __fc); }
1768 __format::__formatter_chrono<_CharT> _M_f;
1771 template<typename _CharT>
1772 struct formatter<chrono::month_weekday, _CharT>
1774 template<typename _ParseContext>
1775 constexpr typename _ParseContext::iterator
1776 parse(_ParseContext& __pc)
1777 { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); }
1779 template<typename _FormatContext>
1780 typename _FormatContext::iterator
1781 format(const chrono::month_weekday& __t, _FormatContext& __fc) const
1782 { return _M_f._M_format(__t, __fc); }
1785 __format::__formatter_chrono<_CharT> _M_f;
1788 template<typename _CharT>
1789 struct formatter<chrono::month_weekday_last, _CharT>
1791 template<typename _ParseContext>
1792 constexpr typename _ParseContext::iterator
1793 parse(_ParseContext& __pc)
1794 { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); }
1796 template<typename _FormatContext>
1797 typename _FormatContext::iterator
1798 format(const chrono::month_weekday_last& __t,
1799 _FormatContext& __fc) const
1800 { return _M_f._M_format(__t, __fc); }
1803 __format::__formatter_chrono<_CharT> _M_f;
1806 template<typename _CharT>
1807 struct formatter<chrono::year_month, _CharT>
1809 template<typename _ParseContext>
1810 constexpr typename _ParseContext::iterator
1811 parse(_ParseContext& __pc)
1812 { return _M_f._M_parse(__pc, __format::_Year|__format::_Month); }
1814 template<typename _FormatContext>
1815 typename _FormatContext::iterator
1816 format(const chrono::year_month& __t, _FormatContext& __fc) const
1817 { return _M_f._M_format(__t, __fc); }
1820 __format::__formatter_chrono<_CharT> _M_f;
1823 template<typename _CharT>
1824 struct formatter<chrono::year_month_day, _CharT>
1826 template<typename _ParseContext>
1827 constexpr typename _ParseContext::iterator
1828 parse(_ParseContext& __pc)
1829 { return _M_f._M_parse(__pc, __format::_Date); }
1831 template<typename _FormatContext>
1832 typename _FormatContext::iterator
1833 format(const chrono::year_month_day& __t, _FormatContext& __fc) const
1834 { return _M_f._M_format(__t, __fc); }
1837 __format::__formatter_chrono<_CharT> _M_f;
1840 template<typename _CharT>
1841 struct formatter<chrono::year_month_day_last, _CharT>
1843 template<typename _ParseContext>
1844 constexpr typename _ParseContext::iterator
1845 parse(_ParseContext& __pc)
1846 { return _M_f._M_parse(__pc, __format::_Date); }
1848 template<typename _FormatContext>
1849 typename _FormatContext::iterator
1850 format(const chrono::year_month_day_last& __t,
1851 _FormatContext& __fc) const
1852 { return _M_f._M_format(__t, __fc); }
1855 __format::__formatter_chrono<_CharT> _M_f;
1858 template<typename _CharT>
1859 struct formatter<chrono::year_month_weekday, _CharT>
1861 template<typename _ParseContext>
1862 constexpr typename _ParseContext::iterator
1863 parse(_ParseContext& __pc)
1864 { return _M_f._M_parse(__pc, __format::_Date); }
1866 template<typename _FormatContext>
1867 typename _FormatContext::iterator
1868 format(const chrono::year_month_weekday& __t,
1869 _FormatContext& __fc) const
1870 { return _M_f._M_format(__t, __fc); }
1873 __format::__formatter_chrono<_CharT> _M_f;
1876 template<typename _CharT>
1877 struct formatter<chrono::year_month_weekday_last, _CharT>
1879 template<typename _ParseContext>
1880 constexpr typename _ParseContext::iterator
1881 parse(_ParseContext& __pc)
1882 { return _M_f._M_parse(__pc, __format::_Date); }
1884 template<typename _FormatContext>
1885 typename _FormatContext::iterator
1886 format(const chrono::year_month_weekday_last& __t,
1887 _FormatContext& __fc) const
1888 { return _M_f._M_format(__t, __fc); }
1891 __format::__formatter_chrono<_CharT> _M_f;
1894 template<typename _Rep, typename _Period, typename _CharT>
1895 struct formatter<chrono::hh_mm_ss<chrono::duration<_Rep, _Period>>, _CharT>
1897 template<typename _ParseContext>
1898 constexpr typename _ParseContext::iterator
1899 parse(_ParseContext& __pc)
1900 { return _M_f._M_parse(__pc, __format::_TimeOfDay); }
1902 template<typename _FormatContext>
1903 typename _FormatContext::iterator
1904 format(const chrono::hh_mm_ss<chrono::duration<_Rep, _Period>>& __t,
1905 _FormatContext& __fc) const
1906 { return _M_f._M_format(__t, __fc); }
1909 __format::__formatter_chrono<_CharT> _M_f;
1912 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
1913 template<typename _CharT>
1914 struct formatter<chrono::sys_info, _CharT>
1916 template<typename _ParseContext>
1917 constexpr typename _ParseContext::iterator
1918 parse(_ParseContext& __pc)
1919 { return _M_f._M_parse(__pc, __format::_ChronoParts{}); }
1921 template<typename _FormatContext>
1922 typename _FormatContext::iterator
1923 format(const chrono::sys_info& __i, _FormatContext& __fc) const
1924 { return _M_f._M_format(__i, __fc); }
1927 __format::__formatter_chrono<_CharT> _M_f;
1930 template<typename _CharT>
1931 struct formatter<chrono::local_info, _CharT>
1933 template<typename _ParseContext>
1934 constexpr typename _ParseContext::iterator
1935 parse(_ParseContext& __pc)
1936 { return _M_f._M_parse(__pc, __format::_ChronoParts{}); }
1938 template<typename _FormatContext>
1939 typename _FormatContext::iterator
1940 format(const chrono::local_info& __i, _FormatContext& __fc) const
1941 { return _M_f._M_format(__i, __fc); }
1944 __format::__formatter_chrono<_CharT> _M_f;
1948 template<typename _Duration, typename _CharT>
1949 struct formatter<chrono::sys_time<_Duration>, _CharT>
1951 template<typename _ParseContext>
1952 constexpr typename _ParseContext::iterator
1953 parse(_ParseContext& __pc)
1955 auto __next = _M_f._M_parse(__pc, __format::_ZonedDateTime);
1956 if constexpr (!__stream_insertable)
1957 if (_M_f._M_spec._M_chrono_specs.empty())
1958 __format::__invalid_chrono_spec(); // chrono-specs can't be empty
1962 template<typename _FormatContext>
1963 typename _FormatContext::iterator
1964 format(const chrono::sys_time<_Duration>& __t,
1965 _FormatContext& __fc) const
1966 { return _M_f._M_format(__t, __fc); }
1969 static constexpr bool __stream_insertable
1970 = requires (basic_ostream<_CharT>& __os,
1971 chrono::sys_time<_Duration> __t) { __os << __t; };
1973 __format::__formatter_chrono<_CharT> _M_f;
1976 template<typename _Duration, typename _CharT>
1977 struct formatter<chrono::utc_time<_Duration>, _CharT>
1978 : __format::__formatter_chrono<_CharT>
1980 template<typename _ParseContext>
1981 constexpr typename _ParseContext::iterator
1982 parse(_ParseContext& __pc)
1983 { return _M_f._M_parse(__pc, __format::_ZonedDateTime); }
1985 template<typename _FormatContext>
1986 typename _FormatContext::iterator
1987 format(const chrono::utc_time<_Duration>& __t,
1988 _FormatContext& __fc) const
1990 // Adjust by removing leap seconds to get equivalent sys_time.
1991 // We can't just use clock_cast because we want to know if the time
1992 // falls within a leap second insertion, and format seconds as "60
".
1993 using chrono::__detail::__utc_leap_second;
1994 using chrono::seconds;
1995 using chrono::sys_time;
1996 using _CDur = common_type_t<_Duration, seconds>;
1997 const auto __li = chrono::get_leap_second_info(__t);
1998 sys_time<_CDur> __s{__t.time_since_epoch() - __li.elapsed};
1999 if (!__li.is_leap_second) [[likely]]
2000 return _M_f._M_format(__s, __fc);
2002 return _M_f._M_format(__utc_leap_second(__s), __fc);
2006 friend formatter<chrono::__detail::__utc_leap_second<_Duration>, _CharT>;
2008 __format::__formatter_chrono<_CharT> _M_f;
2011 template<typename _Duration, typename _CharT>
2012 struct formatter<chrono::tai_time<_Duration>, _CharT>
2013 : __format::__formatter_chrono<_CharT>
2015 template<typename _ParseContext>
2016 constexpr typename _ParseContext::iterator
2017 parse(_ParseContext& __pc)
2018 { return _M_f._M_parse(__pc, __format::_ZonedDateTime); }
2020 template<typename _FormatContext>
2021 typename _FormatContext::iterator
2022 format(const chrono::tai_time<_Duration>& __t,
2023 _FormatContext& __fc) const
2025 // Convert to __local_time_fmt with abbrev "TAI
" and offset 0s.
2027 // Offset is 1970y/January/1 - 1958y/January/1
2028 constexpr chrono::days __tai_offset = chrono::days(4383);
2029 using _CDur = common_type_t<_Duration, chrono::days>;
2030 chrono::local_time<_CDur> __lt(__t.time_since_epoch() - __tai_offset);
2031 const string __abbrev("TAI
", 3);
2032 const chrono::seconds __off = 0s;
2033 const auto __lf = chrono::local_time_format(__lt, &__abbrev, &__off);
2034 return _M_f._M_format(__lf, __fc);
2038 __format::__formatter_chrono<_CharT> _M_f;
2041 template<typename _Duration, typename _CharT>
2042 struct formatter<chrono::gps_time<_Duration>, _CharT>
2043 : __format::__formatter_chrono<_CharT>
2045 template<typename _ParseContext>
2046 constexpr typename _ParseContext::iterator
2047 parse(_ParseContext& __pc)
2048 { return _M_f._M_parse(__pc, __format::_ZonedDateTime); }
2050 template<typename _FormatContext>
2051 typename _FormatContext::iterator
2052 format(const chrono::gps_time<_Duration>& __t,
2053 _FormatContext& __fc) const
2055 // Convert to __local_time_fmt with abbrev "GPS
" and offset 0s.
2057 // Offset is 1980y/January/Sunday[1] - 1970y/January/1
2058 constexpr chrono::days __gps_offset = chrono::days(3657);
2059 using _CDur = common_type_t<_Duration, chrono::days>;
2060 chrono::local_time<_CDur> __lt(__t.time_since_epoch() + __gps_offset);
2061 const string __abbrev("GPS
", 3);
2062 const chrono::seconds __off = 0s;
2063 const auto __lf = chrono::local_time_format(__lt, &__abbrev, &__off);
2064 return _M_f._M_format(__lf, __fc);
2068 __format::__formatter_chrono<_CharT> _M_f;
2071 template<typename _Duration, typename _CharT>
2072 struct formatter<chrono::file_time<_Duration>, _CharT>
2074 template<typename _ParseContext>
2075 constexpr typename _ParseContext::iterator
2076 parse(_ParseContext& __pc)
2077 { return _M_f._M_parse(__pc, __format::_ZonedDateTime); }
2079 template<typename _FormatContext>
2080 typename _FormatContext::iterator
2081 format(const chrono::file_time<_Duration>& __t,
2082 _FormatContext& __ctx) const
2084 using namespace chrono;
2085 return _M_f._M_format(chrono::clock_cast<system_clock>(__t), __ctx);
2089 __format::__formatter_chrono<_CharT> _M_f;
2092 template<typename _Duration, typename _CharT>
2093 struct formatter<chrono::local_time<_Duration>, _CharT>
2095 template<typename _ParseContext>
2096 constexpr typename _ParseContext::iterator
2097 parse(_ParseContext& __pc)
2098 { return _M_f._M_parse(__pc, __format::_DateTime); }
2100 template<typename _FormatContext>
2101 typename _FormatContext::iterator
2102 format(const chrono::local_time<_Duration>& __t,
2103 _FormatContext& __ctx) const
2104 { return _M_f._M_format(__t, __ctx); }
2107 __format::__formatter_chrono<_CharT> _M_f;
2110 template<typename _Duration, typename _CharT>
2111 struct formatter<chrono::__detail::__local_time_fmt<_Duration>, _CharT>
2113 template<typename _ParseContext>
2114 constexpr typename _ParseContext::iterator
2115 parse(_ParseContext& __pc)
2116 { return _M_f._M_parse(__pc, __format::_ZonedDateTime); }
2118 template<typename _FormatContext>
2119 typename _FormatContext::iterator
2120 format(const chrono::__detail::__local_time_fmt<_Duration>& __t,
2121 _FormatContext& __ctx) const
2122 { return _M_f._M_format(__t, __ctx); }
2125 __format::__formatter_chrono<_CharT> _M_f;
2128 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
2129 template<typename _Duration, typename _TimeZonePtr, typename _CharT>
2130 struct formatter<chrono::zoned_time<_Duration, _TimeZonePtr>, _CharT>
2131 : formatter<chrono::__detail::__local_time_fmt<_Duration>, _CharT>
2133 template<typename _FormatContext>
2134 typename _FormatContext::iterator
2135 format(const chrono::zoned_time<_Duration, _TimeZonePtr>& __tp,
2136 _FormatContext& __ctx) const
2138 using chrono::__detail::__local_time_fmt;
2139 using _Base = formatter<__local_time_fmt<_Duration>, _CharT>;
2140 const chrono::sys_info __info = __tp.get_info();
2141 const auto __lf = chrono::local_time_format(__tp.get_local_time(),
2144 return _Base::format(__lf, __ctx);
2149 // Partial specialization needed for %c formatting of __utc_leap_second.
2150 template<typename _Duration, typename _CharT>
2151 struct formatter<chrono::__detail::__utc_leap_second<_Duration>, _CharT>
2152 : formatter<chrono::utc_time<_Duration>, _CharT>
2154 template<typename _FormatContext>
2155 typename _FormatContext::iterator
2156 format(const chrono::__detail::__utc_leap_second<_Duration>& __t,
2157 _FormatContext& __fc) const
2158 { return this->_M_f._M_format(__t, __fc); }
2166 // TODO: from_stream for duration
2168 template<typename _CharT, typename _Traits, typename _Rep, typename _Period,
2169 typename _Alloc = allocator<_CharT>>
2170 basic_istream<_CharT, _Traits>&
2171 from_stream(basic_istream<_CharT, _Traits>& __is, const _CharT* __fmt,
2172 duration<_Rep, _Period>& __d,
2173 basic_string<_CharT, _Traits, _Alloc>* __abbrev = nullptr,
2174 minutes* __offset = nullptr)
2179 template<typename _CharT, typename _Traits>
2180 inline basic_ostream<_CharT, _Traits>&
2181 operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d)
2183 using _Ctx = __conditional_t<is_same_v<_CharT, char>,
2184 format_context, wformat_context>;
2185 using _Str = basic_string_view<_CharT>;
2186 _Str __s = _GLIBCXX_WIDEN("{:02d} is not a valid day
");
2188 __s = __s.substr(0, 6);
2189 auto __u = (unsigned)__d;
2190 __os << std::vformat(__s, make_format_args<_Ctx>(__u));
2194 // TODO from_stream for day
2196 template<typename _CharT, typename _Traits>
2197 inline basic_ostream<_CharT, _Traits>&
2198 operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m)
2200 using _Ctx = __conditional_t<is_same_v<_CharT, char>,
2201 format_context, wformat_context>;
2202 using _Str = basic_string_view<_CharT>;
2203 _Str __s = _GLIBCXX_WIDEN("{:L%b}{} is not a valid month
");
2205 __os << std::vformat(__os.getloc(), __s.substr(0, 6),
2206 make_format_args<_Ctx>(__m));
2209 auto __u = (unsigned)__m;
2210 __os << std::vformat(__s.substr(6), make_format_args<_Ctx>(__u));
2215 // TODO from_stream for month
2217 template<typename _CharT, typename _Traits>
2218 inline basic_ostream<_CharT, _Traits>&
2219 operator<<(basic_ostream<_CharT, _Traits>& __os, const year& __y)
2221 using _Ctx = __conditional_t<is_same_v<_CharT, char>,
2222 format_context, wformat_context>;
2223 using _Str = basic_string_view<_CharT>;
2224 _Str __s = _GLIBCXX_WIDEN("-{:04d} is not a valid year
");
2226 __s = __s.substr(0, 7);
2228 if (__i >= 0) [[likely]]
2229 __s.remove_prefix(1);
2232 __os << std::vformat(__s, make_format_args<_Ctx>(__i));
2236 // TODO from_stream for year
2238 template<typename _CharT, typename _Traits>
2239 inline basic_ostream<_CharT, _Traits>&
2240 operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd)
2242 using _Ctx = __conditional_t<is_same_v<_CharT, char>,
2243 format_context, wformat_context>;
2244 using _Str = basic_string_view<_CharT>;
2245 _Str __s = _GLIBCXX_WIDEN("{:L%a}{} is not a valid weekday
");
2247 __os << std::vformat(__os.getloc(), __s.substr(0, 6),
2248 make_format_args<_Ctx>(__wd));
2251 auto __c = __wd.c_encoding();
2252 __os << std::vformat(__s.substr(6), make_format_args<_Ctx>(__c));
2257 // TODO from_stream for weekday
2259 template<typename _CharT, typename _Traits>
2260 inline basic_ostream<_CharT, _Traits>&
2261 operator<<(basic_ostream<_CharT, _Traits>& __os,
2262 const weekday_indexed& __wdi)
2264 // The standard says to format wdi.weekday() and wdi.index() using
2265 // either "{:L}[{}]
" or "{:L}[{} is not a valid index]
". The {:L} spec
2266 // means to format the weekday using ostringstream, so just do that.
2267 basic_stringstream<_CharT> __os2;
2268 __os2.imbue(__os.getloc());
2269 __os2 << __wdi.weekday();
2270 const auto __i = __wdi.index();
2271 if constexpr (is_same_v<_CharT, char>)
2272 __os2 << std::format("[{}
", __i);
2274 __os2 << std::format(L"[{}
", __i);
2275 basic_string_view<_CharT> __s = _GLIBCXX_WIDEN(" is not a valid index]
");
2276 if (__i >= 1 && __i <= 5)
2277 __os2 << __s.back();
2280 __os << __os2.view();
2284 template<typename _CharT, typename _Traits>
2285 inline basic_ostream<_CharT, _Traits>&
2286 operator<<(basic_ostream<_CharT, _Traits>& __os,
2287 const weekday_last& __wdl)
2289 // As above, just write straight to a stringstream, as if by "{:L}[last]
"
2290 basic_stringstream<_CharT> __os2;
2291 __os2.imbue(__os.getloc());
2292 __os2 << __wdl.weekday() << _GLIBCXX_WIDEN("[last]
");
2293 __os << __os2.view();
2297 template<typename _CharT, typename _Traits>
2298 inline basic_ostream<_CharT, _Traits>&
2299 operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md)
2301 // As above, just write straight to a stringstream, as if by "{:L}/{}
"
2302 basic_stringstream<_CharT> __os2;
2303 __os2.imbue(__os.getloc());
2304 __os2 << __md.month();
2305 if constexpr (is_same_v<_CharT, char>)
2309 __os2 << __md.day();
2310 __os << __os2.view();
2314 // TODO from_stream for month_day
2316 template<typename _CharT, typename _Traits>
2317 inline basic_ostream<_CharT, _Traits>&
2318 operator<<(basic_ostream<_CharT, _Traits>& __os,
2319 const month_day_last& __mdl)
2321 // As above, just write straight to a stringstream, as if by "{:L}/last
"
2322 basic_stringstream<_CharT> __os2;
2323 __os2.imbue(__os.getloc());
2324 __os2 << __mdl.month();
2325 if constexpr (is_same_v<_CharT, char>)
2329 __os << __os2.view();
2333 template<typename _CharT, typename _Traits>
2334 inline basic_ostream<_CharT, _Traits>&
2335 operator<<(basic_ostream<_CharT, _Traits>& __os,
2336 const month_weekday& __mwd)
2338 // As above, just write straight to a stringstream, as if by "{:L}/{:L}
"
2339 basic_stringstream<_CharT> __os2;
2340 __os2.imbue(__os.getloc());
2341 __os2 << __mwd.month();
2342 if constexpr (is_same_v<_CharT, char>)
2346 __os2 << __mwd.weekday_indexed();
2347 __os << __os2.view();
2351 template<typename _CharT, typename _Traits>
2352 inline basic_ostream<_CharT, _Traits>&
2353 operator<<(basic_ostream<_CharT, _Traits>& __os,
2354 const month_weekday_last& __mwdl)
2356 // As above, just write straight to a stringstream, as if by "{:L}/{:L}
"
2357 basic_stringstream<_CharT> __os2;
2358 __os2.imbue(__os.getloc());
2359 __os2 << __mwdl.month();
2360 if constexpr (is_same_v<_CharT, char>)
2364 __os2 << __mwdl.weekday_last();
2365 __os << __os2.view();
2369 template<typename _CharT, typename _Traits>
2370 inline basic_ostream<_CharT, _Traits>&
2371 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym)
2373 // As above, just write straight to a stringstream, as if by "{}/{:L}
"
2374 basic_stringstream<_CharT> __os2;
2375 __os2.imbue(__os.getloc());
2376 __os2 << __ym.year();
2377 if constexpr (is_same_v<_CharT, char>)
2381 __os2 << __ym.month();
2382 __os << __os2.view();
2386 // TODO from_stream for year_month
2388 template<typename _CharT, typename _Traits>
2389 inline basic_ostream<_CharT, _Traits>&
2390 operator<<(basic_ostream<_CharT, _Traits>& __os,
2391 const year_month_day& __ymd)
2393 using _Ctx = __conditional_t<is_same_v<_CharT, char>,
2394 format_context, wformat_context>;
2395 using _Str = basic_string_view<_CharT>;
2396 _Str __s = _GLIBCXX_WIDEN("{:%F} is not a valid date
");
2397 __os << std::vformat(__ymd.ok() ? __s.substr(0, 5) : __s,
2398 make_format_args<_Ctx>(__ymd));
2402 // TODO from_stream for year_month_day
2404 template<typename _CharT, typename _Traits>
2405 inline basic_ostream<_CharT, _Traits>&
2406 operator<<(basic_ostream<_CharT, _Traits>& __os,
2407 const year_month_day_last& __ymdl)
2409 // As above, just write straight to a stringstream, as if by "{}/{:L}
"
2410 basic_stringstream<_CharT> __os2;
2411 __os2.imbue(__os.getloc());
2412 __os2 << __ymdl.year();
2413 if constexpr (is_same_v<_CharT, char>)
2417 __os2 << __ymdl.month_day_last();
2418 __os << __os2.view();
2422 template<typename _CharT, typename _Traits>
2423 inline basic_ostream<_CharT, _Traits>&
2424 operator<<(basic_ostream<_CharT, _Traits>& __os,
2425 const year_month_weekday& __ymwd)
2427 // As above, just write straight to a stringstream, as if by
2429 basic_stringstream<_CharT> __os2;
2430 __os2.imbue(__os.getloc());
2432 if constexpr (is_same_v<_CharT, char>)
2436 __os2 << __ymwd.year() << __slash << __ymwd.month() << __slash
2437 << __ymwd.weekday_indexed();
2438 __os << __os2.view();
2442 template<typename _CharT, typename _Traits>
2443 inline basic_ostream<_CharT, _Traits>&
2444 operator<<(basic_ostream<_CharT, _Traits>& __os,
2445 const year_month_weekday_last& __ymwdl)
2447 // As above, just write straight to a stringstream, as if by
2449 basic_stringstream<_CharT> __os2;
2450 __os2.imbue(__os.getloc());
2452 if constexpr (is_same_v<_CharT, char>)
2456 __os2 << __ymwdl.year() << __slash << __ymwdl.month() << __slash
2457 << __ymwdl.weekday_last();
2458 __os << __os2.view();
2462 template<typename _CharT, typename _Traits, typename _Duration>
2463 inline basic_ostream<_CharT, _Traits>&
2464 operator<<(basic_ostream<_CharT, _Traits>& __os,
2465 const hh_mm_ss<_Duration>& __hms)
2467 return __os << format(__os.getloc(), _GLIBCXX_WIDEN("{:L%T}
"), __hms);
2470 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
2472 template<typename _CharT, typename _Traits>
2473 basic_ostream<_CharT, _Traits>&
2474 operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_info& __i)
2476 __os << '[' << __i.begin << ',' << __i.end
2477 << ',' << hh_mm_ss(__i.offset) << ',' << __i.save
2478 << ',' << __i.abbrev << ']';
2483 template<typename _CharT, typename _Traits>
2484 basic_ostream<_CharT, _Traits>&
2485 operator<<(basic_ostream<_CharT, _Traits>& __os, const local_info& __li)
2488 if (__li.result == local_info::unique)
2492 if (__li.result == local_info::nonexistent)
2493 __os << "nonexistent
";
2495 __os << "ambiguous
";
2496 __os << " local time between
" << __li.first;
2497 __os << " and
" << __li.second;
2503 template<typename _CharT, typename _Traits, typename _Duration,
2504 typename _TimeZonePtr>
2505 inline basic_ostream<_CharT, _Traits>&
2506 operator<<(basic_ostream<_CharT, _Traits>& __os,
2507 const zoned_time<_Duration, _TimeZonePtr>& __t)
2509 __os << format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T %Z}
"), __t);
2514 template<typename _CharT, typename _Traits, typename _Duration>
2515 requires (!treat_as_floating_point_v<typename _Duration::rep>)
2516 && ratio_less_v<typename _Duration::period, days::period>
2517 inline basic_ostream<_CharT, _Traits>&
2518 operator<<(basic_ostream<_CharT, _Traits>& __os,
2519 const sys_time<_Duration>& __tp)
2521 __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T}
"), __tp);
2525 template<typename _CharT, typename _Traits>
2526 inline basic_ostream<_CharT, _Traits>&
2527 operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_days& __dp)
2529 __os << year_month_day{__dp};
2533 // TODO: from_stream for sys_time
2535 template<typename _CharT, typename _Traits, typename _Duration>
2536 inline basic_ostream<_CharT, _Traits>&
2537 operator<<(basic_ostream<_CharT, _Traits>& __os,
2538 const utc_time<_Duration>& __t)
2540 __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T}
"), __t);
2544 // TODO: from_stream for utc_time
2546 template<typename _CharT, typename _Traits, typename _Duration>
2547 inline basic_ostream<_CharT, _Traits>&
2548 operator<<(basic_ostream<_CharT, _Traits>& __os,
2549 const tai_time<_Duration>& __t)
2551 __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T}
"), __t);
2555 // TODO: from_stream for tai_time
2557 template<typename _CharT, typename _Traits, typename _Duration>
2558 inline basic_ostream<_CharT, _Traits>&
2559 operator<<(basic_ostream<_CharT, _Traits>& __os,
2560 const gps_time<_Duration>& __t)
2562 __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T}
"), __t);
2566 // TODO: from_stream for gps_time
2569 template<typename _CharT, typename _Traits, typename _Duration>
2570 inline basic_ostream<_CharT, _Traits>&
2571 operator<<(basic_ostream<_CharT, _Traits>& __os,
2572 const file_time<_Duration>& __t)
2574 __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{:L%F %T}
"), __t);
2578 // TODO: from_stream for file_time
2580 template<typename _CharT, typename _Traits, typename _Duration>
2581 inline basic_ostream<_CharT, _Traits>&
2582 operator<<(basic_ostream<_CharT, _Traits>& __os,
2583 const local_time<_Duration>& __lt)
2585 __os << sys_time<_Duration>{__lt.time_since_epoch()};
2589 // TODO: from_stream for local_time
2590 #undef _GLIBCXX_WIDEN
2593 } // namespace chrono
2595 _GLIBCXX_END_NAMESPACE_VERSION
2600 #endif //_GLIBCXX_CHRONO_IO_H
basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const duration< _Rep, _Period > &__d)
duration< int64_t, ratio< 86400 > > days
days
__detail::__local_time_fmt< _Duration > local_time_format(local_time< _Duration > __time, const string *__abbrev=nullptr, const seconds *__offset_sec=nullptr)
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
ISO C++ entities toplevel namespace is std.
constexpr bitset< _Nb > operator|(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
locale imbue(const locale &__loc)
Moves to a new locale.
Template class basic_ostream.
Controlling output for std::string.
Provides output iterator semantics for streambufs.
Provides compile-time rational arithmetic.
A non-owning reference to a string.
chrono::duration represents a distance between two points in time
chrono::time_point represents a point in time as measured by a clock
streamsize precision() const
Flags access.
fmtflags flags() const
Access to format flags.
static const locale & classic()
Return reference to the C locale.