@@ -334,7 +334,7 @@ std::string format(const std::string& format, const time_point<seconds>& tp,
334334 const std::tm tm = ToTM (al);
335335
336336 // Scratch buffer for internal conversions.
337- char buf[3 + kDigits10_64 ]; // enough for longest conversion
337+ char buf[6 + ( kDigits10_64 + 2 ) ]; // enough for longest conversion %F
338338 char * const ep = buf + sizeof (buf);
339339 char * bp; // works back from ep
340340
@@ -378,7 +378,7 @@ std::string format(const std::string& format, const time_point<seconds>& tp,
378378 if (cur == end || (cur - percent) % 2 == 0 ) continue ;
379379
380380 // Simple specifiers that we handle ourselves.
381- if (strchr (" YmdeUuWwHMSzZs %" , *cur)) {
381+ if (strchr (" YmdeFUuWwHMSTzZs %" , *cur)) {
382382 if (cur - 1 != pending) {
383383 FormatTM (&result, std::string (pending, cur - 1 ), tm);
384384 }
@@ -399,6 +399,14 @@ std::string format(const std::string& format, const time_point<seconds>& tp,
399399 if (*cur == ' e' && *bp == ' 0' ) *bp = ' ' ; // for Windows
400400 result.append (bp, static_cast <std::size_t >(ep - bp));
401401 break ;
402+ case ' F' :
403+ bp = Format02d (ep, al.cs .day ());
404+ *--bp = ' -' ;
405+ bp = Format02d (bp, al.cs .month ());
406+ *--bp = ' -' ;
407+ bp = Format64 (bp, 0 , al.cs .year ());
408+ result.append (bp, static_cast <std::size_t >(ep - bp));
409+ break ;
402410 case ' U' :
403411 bp = Format02d (ep, ToWeek (civil_day (al.cs ), weekday::sunday));
404412 result.append (bp, static_cast <std::size_t >(ep - bp));
@@ -427,6 +435,14 @@ std::string format(const std::string& format, const time_point<seconds>& tp,
427435 bp = Format02d (ep, al.cs .second ());
428436 result.append (bp, static_cast <std::size_t >(ep - bp));
429437 break ;
438+ case ' T' :
439+ bp = Format02d (ep, al.cs .second ());
440+ *--bp = ' :' ;
441+ bp = Format02d (bp, al.cs .minute ());
442+ *--bp = ' :' ;
443+ bp = Format02d (bp, al.cs .hour ());
444+ result.append (bp, static_cast <std::size_t >(ep - bp));
445+ break ;
430446 case ' z' :
431447 bp = FormatOffset (ep, al.offset , " " );
432448 result.append (bp, static_cast <std::size_t >(ep - bp));
@@ -764,6 +780,20 @@ bool parse(const std::string& format, const std::string& input,
764780 data = ParseInt (data, 2 , 1 , 31 , &tm.tm_mday );
765781 week_num = -1 ;
766782 continue ;
783+ case ' F' :
784+ data = ParseInt (data, 0 , kyearmin, kyearmax, &year);
785+ if (data != nullptr ) {
786+ saw_year = true ;
787+ data = (*data == ' -' ? data + 1 : nullptr );
788+ }
789+ data = ParseInt (data, 2 , 1 , 12 , &tm.tm_mon );
790+ if (data != nullptr ) {
791+ tm.tm_mon -= 1 ;
792+ data = (*data == ' -' ? data + 1 : nullptr );
793+ }
794+ data = ParseInt (data, 2 , 1 , 31 , &tm.tm_mday );
795+ week_num = -1 ;
796+ continue ;
767797 case ' U' :
768798 data = ParseInt (data, 0 , 0 , 53 , &week_num);
769799 week_start = weekday::sunday;
@@ -789,13 +819,20 @@ bool parse(const std::string& format, const std::string& input,
789819 case ' S' :
790820 data = ParseInt (data, 2 , 0 , 60 , &tm.tm_sec );
791821 continue ;
822+ case ' T' :
823+ data = ParseInt (data, 2 , 0 , 23 , &tm.tm_hour );
824+ twelve_hour = false ;
825+ data = (data != nullptr && *data == ' :' ? data + 1 : nullptr );
826+ data = ParseInt (data, 2 , 0 , 59 , &tm.tm_min );
827+ data = (data != nullptr && *data == ' :' ? data + 1 : nullptr );
828+ data = ParseInt (data, 2 , 0 , 60 , &tm.tm_sec );
829+ continue ;
792830 case ' I' :
793831 case ' l' :
794832 case ' r' : // probably uses %I
795833 twelve_hour = true ;
796834 break ;
797835 case ' R' : // uses %H
798- case ' T' : // uses %H
799836 case ' c' : // probably uses %H
800837 case ' X' : // probably uses %H
801838 twelve_hour = false ;
0 commit comments