The Boost C++ Libraries

Formatted Input and Output

The sample programs described so far in this chapter write results in the format 2014-May-12. Boost.DateTime lets you display results in different formats. Calendar dates and times can be formatted using boost::date_time::date_facet and boost::date_time::time_facet.

Boost.DateTime uses the concept of locales from the standard. To format a calendar date, an object of type boost::date_time::date_facet must be created and installed within a locale. A string describing the new format is passed to the constructor of boost::date_time::date_facet. Example 36.20 passes %A, %d %B %Y, which specifies that the day of the week is followed by the date with the month written in full: Monday, 12 May 2014.

Example 36.20. A user-defined format for a date
#include <boost/date_time/gregorian/gregorian.hpp>
#include <iostream>
#include <locale>

using namespace boost::gregorian;

int main()
{
  date d{2014, 5, 12};
  date_facet *df = new date_facet{"%A, %d %B %Y"};
  std::cout.imbue(std::locale{std::cout.getloc(), df});
  std::cout << d << '\n';
}

Boost.DateTime provides numerous format flags, each of which consists of the percent sign followed by a character. The documentation for Boost.DateTime contains a complete overview of all supported flags.

If a program is used by people located in Germany or German-speaking countries, it is preferable to display both the weekday and the month in German rather than in English.

Example 36.21. Changing names of weekdays and months
#include <boost/date_time/gregorian/gregorian.hpp>
#include <string>
#include <vector>
#include <locale>
#include <iostream>

using namespace boost::gregorian;

int main()
{
  std::locale::global(std::locale{"German"});
  std::string months[12]{"Januar", "Februar", "M\xe4rz", "April",
    "Mai", "Juni", "Juli", "August", "September", "Oktober",
    "November", "Dezember"};
  std::string weekdays[7]{"Sonntag", "Montag", "Dienstag",
    "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
  date d{2014, 5, 12};
  date_facet *df = new date_facet{"%A, %d. %B %Y"};
  df->long_month_names(std::vector<std::string>{months, months + 12});
  df->long_weekday_names(std::vector<std::string>{weekdays,
    weekdays + 7});
  std::cout.imbue(std::locale{std::cout.getloc(), df});
  std::cout << d << '\n';
}

The names for weekdays and months can be changed by passing vectors containing the desired names to the member functions long_month_names() and long_weekday_names() of the class boost::date_time::date_facet. Example 36.21 now writes Montag, 12. Mai 2014 to the standard output stream.

Note

To run the example on a POSIX operating system, replace German with de_DE and make sure the locale for German is installed.

Boost.DateTime is flexible with regard to formatted input and output. Besides the output classes boost::date_time::date_facet and boost::date_time::time_facet, the classes boost::date_time::date_input_facet and boost::date_time::time_input_facet are available for formatted input. All four classes provide member functions to configure the input and output of different objects provided by Boost.DateTime. For example, it is possible to specify how periods of type boost::gregorian::date_period are input and output. To see all of the possibilities for formatted input and output, review the documentation for Boost.DateTime.