std::time_p...put::do_put(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

🌸 NAME 🌸

std::time_put::put, std::time_put::do_put β€” std::time_put::put, std::time_put::do_put

okay so bestie, welcome to this C++ Standard Library page πŸ’–. It’s the one for std::time_put::put and std::time_put::do_put, and we’re gonna get you comfy with every little detail, no cap ✨.


πŸ¦‹ Synopsis πŸ¦‹

Defined in header <locale>
public:

iter_type put( iter_type out, std::ios_base& str,                (1)
               char_type fill, const std::tm* t,

               const CharT* fmtbeg, const CharT* fmtend ) const;
public:

iter_type put( iter_type out, std::ios_base& str,                (2)
               char_type fill, const std::tm* t,

               char format, char modifier = 0 ) const;
protected:

virtual iter_type do_put( iter_type out, std::ios_base& str,     (3)
                          char_type fill, const std::tm* t,

                          char format, char modifier ) const;

πŸŽ€ DESCRIPTION πŸŽ€

So what’s the vibe? This thing converts the calendar date and time stored in the std::tm object pointed to by t into a character string, according to the format string [fmtbeg, fmtend) πŸ’…. The format string is the same as used by std::strftime, but each format specifier is processed by an individual call to do_put(), which can be customized by extending this facet 🫢.

  1. Steps through the character sequence [fmtbeg, fmtend), examining the characters. Every character that is not a part of a format sequence is written to the output iterator out immediately. To identify format sequences, this function narrows the next character c in [fmtbeg, fmtend) as if by std::ctype<char_type>(str.getloc()).narrow(c, 0) and if it equals '%', the next one or two characters are compared to the list of format sequences recognized by std::strftime plus any additional implementation-defined formats supported by this locale. For each valid format sequence, a call to do_put(out, str, fill, t, format, modifier) is made, where format is the format sequence character, and modifier is the optional format sequence modifier ('E' or 'O'). A value of '\0' is used if the modifier is absent ✨.
  2. Calls the do_put member function of the most derived class πŸ‘‘.
  3. Converts the calendar date and time stored in the std::tm object pointed to by t into a character string, according to the format conversion sequence formed by concatenating '%', the value of modifier if not '\0', and the value of format. The format is interpreted the same way as the function std::strftime, except that the formats that are described as locale-dependent are defined by this locale, and additional format specifiers may be supported (the fill argument is provided for these implementation-defined format specifiers to use). The string is written to the output iterator out πŸ’–.

🌸 Parameters 🌸

  • out β€” the output iterator where the result of the conversion gets written πŸ’–
  • str β€” a stream object that this function uses to obtain locale facets when it needs them, e.g. std::ctype to narrow characters
  • t β€” pointer to the std::tm object from which the date/time values are obtained
  • fmtbeg β€” pointer to the first character of a sequence of char_type characters specifying the conversion format ✨
  • fmtend β€” pointer one past the last character of a sequence of char_type characters specifying the conversion format
  • fill β€” fill character (usually space)
  • format β€” the character that names a conversion specifier
  • modifier β€” the optional modifier that may appear between % and the conversion specifier

✨ Format string ✨

Okay so the format string is literally just zero or more conversion specifiers plus ordinary characters (everything except %). All ordinary characters β€” including the terminating null character β€” are copied to the output string without modification, no questions asked 🫢

Each conversion specification begins with a % character, optionally followed by an E or O modifier (which is ignored if the locale doesn't support it, so don't stress), and then followed by the character that determines the behavior of the specifier. The following format specifiers are available πŸ‘‘

  • % β€” writes a literal %. The full conversion specification must be %% πŸ’…
  • %n (C++11) β€” writes a newline character
  • %t (C++11) β€” writes a horizontal tab character

πŸ‘‘ Year πŸ‘‘

  • %Y β€” writes year as a decimal number, e.g. 2017. used field: tm_year
  • %EY (C++11) β€” writes year in the alternative representation, e.g. 平成23εΉ΄ (year Heisei 23) instead of 2011εΉ΄ (year 2011) in the ja_JP locale. used field: tm_year
  • %y β€” writes last 2 digits of year as a decimal number (range [00,99]). used field: tm_year
  • %Oy (C++11) β€” writes last 2 digits of year using the alternative numeric system, e.g. 十一 instead of 11 in the ja_JP locale. used field: tm_year
  • %Ey (C++11) β€” writes year as offset from locale's alternative calendar period %EC (locale-dependent). used field: tm_year
  • %C (C++11) β€” writes first 2 digits of year as a decimal number (range [00,99]). used field: tm_year
  • %EC (C++11) β€” writes name of the base year (period) in the locale's alternative representation, e.g. 平成 (Heisei era) in ja_JP. used field: tm_year
  • %G (C++11) β€” writes ISO 8601 week-based year, i.e. the year that contains the specified week. used fields: tm_year, tm_wday, tm_yday

In ISO 8601 weeks begin with Monday and the first week of the year must satisfy the following requirements:

  • Includes January 4
  • Includes first Thursday of the year
  • %g (C++11) β€” writes last 2 digits of ISO 8601 week-based year, i.e. the year that contains the specified week (range [00,99]). used fields: tm_year, tm_wday, tm_yday

In ISO 8601 weeks begin with Monday and the first week of the year must satisfy the following requirements:

  • Includes January 4
  • Includes first Thursday of the year

🌸 Month 🌸

  • %b β€” writes abbreviated month name, e.g. Oct (locale dependent). used field: tm_mon
  • %h (C++11) β€” synonym of %b. used field: tm_mon
  • %B β€” writes full month name, e.g. October (locale dependent). used field: tm_mon
  • %m β€” writes month as a decimal number (range [01,12]). used field: tm_mon
  • %Om (C++11) β€” writes month using the alternative numeric system, e.g. 十二 instead of 12 in the ja_JP locale. used field: tm_mon

πŸ¦‹ Week πŸ¦‹

  • %U β€” writes week of the year as a decimal number (Sunday is the first day of the week) (range [00,53]). used fields: tm_year, tm_wday, tm_yday
  • %OU (C++11) β€” writes week of the year, as by %U, using the alternative numeric system, e.g. δΊ”εδΊŒ instead of 52 in the ja_JP locale. used fields: tm_year, tm_wday, tm_yday
  • %W β€” writes week of the year as a decimal number (Monday is the first day of the week) (range [00,53]). used fields: tm_year, tm_wday, tm_yday
  • %OW (C++11) β€” writes week of the year, as by %W, using the alternative numeric system, e.g. δΊ”εδΊŒ instead of 52 in the ja_JP locale. used fields: tm_year, tm_wday, tm_yday
  • %V (C++11) β€” writes ISO 8601 week of the year (range [01,53]). used fields: tm_year, tm_wday, tm_yday

In ISO 8601 weeks begin with Monday and the first week of the year must satisfy the following requirements:

  • Includes January 4
  • Includes first Thursday of the year
  • %OV (C++11) β€” writes week of the year, as by %V, using the alternative numeric system, e.g. δΊ”εδΊŒ instead of 52 in the ja_JP locale. used fields: tm_year, tm_wday, tm_yday

πŸŽ€ Day of the year/month πŸŽ€

  • %j β€” writes day of the year as a decimal number (range [001,366]). used field: tm_yday
  • %d β€” writes day of the month as a decimal number (range [01,31]). used field: tm_mday
  • %Od (C++11) β€” writes zero-based day of the month using the alternative numeric system, e.g. δΊŒεδΈƒ instead of 27 in the ja_JP locale. used field: tm_mday
  • %e (C++11) β€” writes day of the month as a decimal number (range [1,31]). Single digit is preceded by a space. used field: tm_mday
  • %Oe (C++11) β€” writes one-based day of the month using the alternative numeric system, e.g. δΊŒεδΈƒ instead of 27 in the ja_JP locale. Single character is preceded by a space. used field: tm_mday

πŸ’œ Day of the week πŸ’œ

  • %a β€” writes abbreviated weekday name, e.g. Fri (locale dependent). used field: tm_wday
  • %A β€” writes full weekday name, e.g. Friday (locale dependent). used field: tm_wday
  • %w β€” writes weekday as a decimal number, where Sunday is 0 (range [0-6]). used field: tm_wday
  • %Ow (C++11) β€” writes weekday, where Sunday is 0, using the alternative numeric system, e.g. 二 instead of 2 in the ja_JP locale. used field: tm_wday
  • %u (C++11) β€” writes weekday as a decimal number, where Monday is 1 (ISO 8601 format) (range [1-7]). used field: tm_wday
  • %Ou (C++11) β€” writes weekday, where Monday is 1, using the alternative numeric system, e.g. 二 instead of 2 in the ja_JP locale. used field: tm_wday

⭐ Hour, minute, second ⭐

  • %H β€” writes hour as a decimal number, 24 hour clock (range [00-23]). used field: tm_hour
  • %OH (C++11) β€” writes hour from 24-hour clock using the alternative numeric system, e.g. 十八 instead of 18 in the ja_JP locale. used field: tm_hour
  • %I β€” writes hour as a decimal number, 12 hour clock (range [01,12]). used field: tm_hour
  • %OI (C++11) β€” writes hour from 12-hour clock using the alternative numeric system, e.g. ε…­ instead of 06 in the ja_JP locale. used field: tm_hour
  • %M β€” writes minute as a decimal number (range [00,59]). used field: tm_min
  • %OM (C++11) β€” writes minute using the alternative numeric system, e.g. δΊŒεδΊ” instead of 25 in the ja_JP locale. used field: tm_min
  • %S β€” writes second as a decimal number (range [00,60]). used field: tm_sec
  • %OS (C++11) β€” writes second using the alternative numeric system, e.g. δΊŒεε›› instead of 24 in the ja_JP locale. used field: tm_sec

🌈 Other 🌈

  • %c β€” writes standard date and time string, e.g. Sun Oct 17 04:41:13 2010 (locale dependent). used fields: all
  • %Ec (C++11) β€” writes alternative date and time string, e.g. using 平成23εΉ΄ (year Heisei 23) instead of 2011εΉ΄ (year 2011) in the ja_JP locale. used fields: all
  • %x β€” writes localized date representation (locale dependent). used fields: all
  • %Ex (C++11) β€” writes alternative date representation, e.g. using 平成23εΉ΄ (year Heisei 23) instead of 2011εΉ΄ (year 2011) in the ja_JP locale. used fields: all
  • %X β€” writes localized time representation, e.g. 18:40:20 or 6:40:20 PM (locale dependent). used fields: all
  • %EX (C++11) β€” writes alternative time representation (locale dependent). used fields: all
  • %D (C++11) β€” equivalent to "%m/%d/%y". used fields: tm_mon, tm_mday, tm_year
  • %F (C++11) β€” equivalent to "%Y-%m-%d" (the ISO 8601 date format). used fields: tm_mon, tm_mday, tm_year
  • %r (C++11) β€” writes localized 12-hour clock time (locale dependent). used fields: tm_hour, tm_min, tm_sec
  • %R (C++11) β€” equivalent to "%H:%M". used fields: tm_hour, tm_min
  • %T (C++11) β€” equivalent to "%H:%M:%S" (the ISO 8601 time format). used fields: tm_hour, tm_min, tm_sec
  • %p β€” writes localized a.m. or p.m. (locale dependent). used field: tm_hour
  • %z (C++11) β€” writes offset from UTC in the ISO 8601 format (e.g. -0430), or no characters if the time zone information is not available. used field: tm_isdst
  • %Z β€” writes locale-dependent time zone name or abbreviation, or no characters if the time zone information is not available. used field: tm_isdst

πŸ”₯ Return value πŸ”₯

Iterator pointing one past the last character that was produced. That's it, that's the whole vibe πŸ’…

πŸ’€ Notes πŸ’€

No error handling is provided. Not me, not the standard library, nobody πŸ™ˆ

The fill character is provided for those implementation-defined format specifiers and for the user-defined overrides of do_put() that use padding and filling logic. Such implementations typically make use of the formatting flags from str ✨

🌸 EXAMPLE 🌸

ok so here's the whole thing in action, bestie β€” a full little program that shows you do_put (well, put) doing its multilingual thing:

// Run this code

#include <iostream>
#include <sstream>
#include <iomanip>
#include <ctime>

void try_time_put(const std::tm* t, const std::string& fmt)
{
    std::cout.imbue(std::locale());
    std::cout << "In the locale '" << std::cout.getloc().name() << "' : '";

    std::use_facet<std::time_put<char>>(std::cout.getloc()).put(
        {std::cout}, std::cout, ' ', t, &fmt[0], &fmt[0] + fmt.size());

    std::cout << "'\n";
}

int main()
{
    std::time_t t = std::time(NULL);
    std::tm tm = *std::localtime(&t);

    std::string fmt = "%c";
    std::cout << "Using the format string '" << fmt
              << "' to format the time: " << std::ctime(&t) << '\n';

    std::locale::global(std::locale("de_DE.utf8"));
    try_time_put(&tm, fmt);

    std::locale::global(std::locale("el_GR.utf8"));
    try_time_put(&tm, fmt);

    std::locale::global(std::locale("ja_JP.utf8"));
    try_time_put(&tm, fmt);
}

and the output it could spit at you is giving ✨international icon✨:

Using the format string '%c' to format the time: Mon Feb 11 22:58:50 2013

In the locale 'de_DE.utf8' : 'Mo 11 Feb 2013 23:02:38 EST'
In the locale 'el_GR.utf8' : 'ΔΡυ 11 ΦΡβ 2013 11:02:38 ΞΌΞΌ EST'
In the locale 'ja_JP.utf8' : '2013εΉ΄02月11ζ—₯ 23ζ™‚02εˆ†38η§’'

like… same std::tm, same format string, three completely different fits. that's the whole point of facets fr fr πŸ’…


🩹 Defect reports

so sometimes the standard itself had a little oopsie, and these behavior-changing defect reports got applied retroactively to previously published C++ standards. it's giving "we fixed the past" energy:

  • LWG 164 β€” applied to C++98. as published, the purpose of the parameter fill was not clear β†’ correct behavior: made clear.

that's it, that's the list. one glorious little clarification πŸŽ€


πŸ‘€ See also

other functions in the same friend group, iykyk:

  • put_time (C++11) β€” formats and outputs a date/time value according to the specified format. function template. the glow-up cousin 🫢
  • do_get [virtual] (C++11) β€” extracts date/time components from input stream, according to the specified format. virtual protected member function of std::time_get<CharT,InputIt>. basically the read side of the same coin, no cap.

okay that's the whole page, you made it, I'm so proud of you πŸ˜­πŸ’– go forth and format timestamps in every locale you can get your hands on. this was sourced from cppreference.com and the doc is dated 2024.06.10 β€” slay, periodt, bye bestie πŸ¦‹βœ¨

πŸ“¦ where this page comes from