Search code examples
c++datetimeiomanipconversion-specifierdayofmonth

Does put_time Have a Conversion Specifier Which Outputs Single Digit Days of the Month Without a Preceding Character


put_time provides 2 conversion specifiers for outputting day of the month:

  1. %d: "Day of the month, zero-padded (01-31)"
  2. %e: "Day of the month, space-padded ( 1-31)"

Note that neither of these conversion specifiers will allow me to output a non-padded day of the month. So for example, given tm tmb, if I want to output the day of the month as:

Feb 8 '18

I could do: cout << put_time(&tmb, "%b%e '%y")

But that on the 10th that will output:

Feb10 '18

Thus I must do the janky: cout << put_time(&tmb, "%b ") << tmb.tm_mday << put_time(&tmb, " '%y")

Is there a conversion specifier that I can use to get this all in a single put_time call?


Solution

  • To answer this I've pulled what I believe is a comprehensive list of the conversion specifiers from here: http://en.cppreference.com/w/cpp/io/manip/put_time and bundled them into a simple program:

    tm tmb = { 5, 6, 7, 8, 9, 10 };
    
    mktime(&tmb);
    
    for(const auto i : { "%%", "%n", "%t", "%Y", "%EY", "%y", "%Oy", "%Ey", "%C", "%EC", "%G", "%g", "%b", "%h", "%B", "%m", "%Om", "%U", "%OU", "%W", "%OW", "%V", "%OV", "%j", "%d", "%Od", "%e", "%Oe", "%a", "%A", "%w", "%Ow", "%u", "%Ou", "%H", "%OH", "%I", "%OI", "%M", "%OM", "%S", "%OS", "%c", "%Ec", "%x", "%Ex", "%X", "%EX", "%D", "%F", "%r", "%R", "%T", "%p", "%z", "%Z" } ) {
        cout << i << "\t|\t\"" << put_time(&tmb, i) << "\"\n";
    }
    

    The output of this looks like this:

    %%  |   "%"
    %n  |   "
    "
    %t  |   "   "
    %Y  |   "1910"
    %EY |   "1910"
    %y  |   "10"
    %Oy |   "10"
    %Ey |   "10"
    %C  |   "19"
    %EC |   "19"
    %G  |   "1910"
    %g  |   "10"
    %b  |   "Oct"
    %h  |   "Oct"
    %B  |   "October"
    %m  |   "10"
    %Om |   "10"
    %U  |   "40"
    %OU |   "40"
    %W  |   "40"
    %OW |   "40"
    %V  |   "40"
    %OV |   "40"
    %j  |   "281"
    %d  |   "08"
    %Od |   "08"
    %e  |   " 8"
    %Oe |   " 8"
    %a  |   "Sat"
    %A  |   "Saturday"
    %w  |   "6"
    %Ow |   "6"
    %u  |   "6"
    %Ou |   "6"
    %H  |   "07"
    %OH |   "07"
    %I  |   "07"
    %OI |   "07"
    %M  |   "06"
    %OM |   "06"
    %S  |   "05"
    %OS |   "05"
    %c  |   "Sat Oct  8 07:06:05 1910"
    %Ec |   "Sat Oct  8 07:06:05 1910"
    %x  |   "10/08/10"
    %Ex |   "10/08/10"
    %X  |   "07:06:05"
    %EX |   "07:06:05"
    %D  |   "10/08/10"
    %F  |   "1910-10-08"
    %r  |   "07:06:05 AM"
    %R  |   "07:06"
    %T  |   "07:06:05"
    %p  |   "AM"
    %z  |   "+0000"
    %Z  |   "UTC"
    

    The field in question is the tmb.tm_mday which is populated with an 8. Thus what you'd need here is a value in the table of "8". A quick search will demonstrate there isn't one. Thus, the answer to your question is: There is no conversion specifier which outputs single digit days of the month without a preceding character. You will have to use a workaround similar to what you've proffered in the question.