//
//  timeput.cpp
//

#include <ctime>      // for struct tm
#include <iostream>   // for cout, endl
#include <locale>     // for locale, time_put
#include <sstream>

int main ()
{
    // zero-out all members (including any non-standard
    // ones) std::tm t = std::tm ();
    // assign individual members being careful to
    // avoid relying on the implementation-defined
    // layout of the struct
    tm t;
    t.tm_sec   = 56;   // seconds
    t.tm_min   = 34;   // minutes
    t.tm_hour  = 14;   // hours (i.e., 2 PM)
    t.tm_mday  = 29;   // day of month
    t.tm_mon   =  1;   // month (Feb)
    t.tm_year  = 104;   // years since 1900
                      // (i.e., 1984)
    t.tm_yday  = 59;   // day of the year
    t.tm_wday  =  3;   // day of the week (Wednesday)
    t.tm_isdst =  0;   // Daylight Saving Time

    const char* const fmt[] = {
      "%a", "%A", "%b", "%B", "%c", "%C", "%d", "%D",
      "%e", "%F", "%g", "%G", "%h", "%H", "%I", "%j",
      "%k", "%l", "%m", "%M", "%n", "%p", "%r", "%R",
      "%S", "%t", "%T", "%u", "%U", "%V", "%w", "%W", "%x",
      "%X", "%y", "%Y", "%z", "%Z", "%%", "%Ec", "%EC", "%Ex",
      "%EX", "%Ey", "%EY", "%Od", "%Oe", "%OH", "%OI", "%Om",
      "%OM", "%OS", "%Ou", "%OU", "%OV", "%Ow", "%OW", "%Oy"         
    };

    std::locale the_locale(""); //"When name is the empty string (""), the resulting locale object is equal to locale(setlocale(LC_ALL, "")), which means that the resulting locale is determined by the values of the LANG and LC_XXX environment variables."

    // retrieve the time_put facet installed in cout
    const std::time_put<char> &tput =
        std::use_facet<std::time_put<char> >(the_locale);

    // print out the value of t formatted according to each
    // of the format/ specifiers defined above 
    for (std::size_t i = 0; i != sizeof fmt / sizeof *fmt; ++i) {
        std::cout << "   \"" << fmt [i] << "\"   \"";

        if ('n' == fmt [i][1])
            std::cout << "\\n";
        else if ('t' == fmt [i][1])
            std::cout << "\\t";
        else
        {
            typedef std::stringstream type_stream;
            type_stream the_stream;
            the_stream.imbue(the_locale);

            tput.put (std::ostreambuf_iterator<char>(the_stream.rdbuf ()),
                      the_stream, ' ', &t, fmt [i],
                      fmt [i] + std::char_traits<char>::length (fmt [i]));

            std::cout << the_stream.str();
        }

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

    return 0;
}
