Date Time IO Tutorial Date Time IO Tutorial Basic Use | Format Strings | Content Strings Basic Use Facets are automatically imbued when operators '>>' and '<<' are called. The list of date_time objects that can be streamed are: Gregorian date, days, date_period, greg_month, greg_weekday, greg_year, partial_date, nth_day_of_the_week_in_month, first_day_of_the_week_in_month, last_day_of_the_week_in_month, first_day_of_the_week_after, first_day_of_the_week_before Posix_time ptime, time_period, time_duration Local_time local_date_time The following example is of the basic use of the new IO code, utilizing all the defaults. (this example can be found in the libs/date_time/examples/tutorial directory) > pt; cout << pt << endl; // "2004-Feb-29 12:34:56.000789" ss.str(""); ss << pt << " EDT-05EDT,M4.1.0,M10.5.0"; local_date_time ldt(not_a_date_time); ss >> ldt; cout << ldt << endl; // " 2004-Feb-29 12:34:56.000789 EDT" ]]> This example used the default settings for the input and output facets. The default formats are such that interoperability like that shown in the example is possible. NOTE: Input streaming of local_date_time can only be done with a posix time zone string(link). The default output format uses a time zone abbreviation. The format can be changed so out and in match (as we will see later in this tutorial). Format Strings The format strings control the order, type, and style of the date/time elements used. The facets provide some predefined formats (iso_format_specifier, iso_format_extended_specifier, and default_date_format) but the user can easily create their own. (continued from previous example) format("%a %b %d, %H:%M %z"); ss.str(""); ss << ldt; cout << ss.str() << endl; // "Sun Feb 29, 12:34 EDT" output_facet->format(local_time_facet::iso_time_format_specifier); ss.str(""); ss << ldt; cout << ss.str() << endl; // "20040229T123456.000789-0500" output_facet->format(local_time_facet::iso_time_format_extended_specifier); ss.str(""); ss << ldt; cout << ss.str() << endl; // "2004-02-29 12:34:56.000789-05:00" ]]> Format strings are not limited to date/time elements. Extra verbiage can be placed in a format string. NOTE: When extra verbiage is present in an input format, the data being input must also contain the exact verbiage. (continued from previous example) format(my_format.c_str()); input_facet->format(my_format.c_str()); ss.str(""); ss << ldt; cout << ss.str() << endl; ss.str("The extended ordinal time 2005-128T12:15 can also be \ represented as Sunday May 08, 2005"); ss >> ldt; cout << ldt << endl; ]]> Content Strings So far we've shown how a user can achieve a great deal of customization with very little effort by using formats. Further customization can be achieved through user defined elements (ie strings). The elements that can be customized are: Special value names, month names, month abbreviations, weekday names, weekday abbreviations, delimiters of the date/time periods, and the phrase elements of the date_generators. The default values for these are as follows: Special values not-a-date-time, -infinity, +infinity, minimum-date-time, maximum-date-time Months English calendar and three letter abbreviations Weekdays English calendar and three letter abbreviations Date generator phrase elements first, second, third, fourth, fifth, last, before, after, of NOTE: We've shown earlier that the components of a date/time representation can be re-ordered via the format string. This is not the case with date_generators. The elements themselves can be customized but their order cannot be changed. (continued from previous example) format(local_time_facet::default_time_format); input_facet->format(local_time_input_facet::default_time_input_format); // create custom special_values parser and formatter objetcs // and add them to the facets string sv[5] = {"nadt","neg_inf", "pos_inf", "min_dt", "max_dt" }; vector sv_names(&sv[0], &sv[5]); special_values_parser sv_parser(sv_names.begin(), sv_names.end()); special_values_formatter sv_formatter(sv_names.begin(), sv_names.end()); output_facet->special_values_formatter(sv_formatter); input_facet->special_values_parser(sv_parser); ss.str(""); ldt = local_date_time(not_a_date_time); ss << ldt; cout << ss.str() << endl; // "nadt" ss.str("min_dt"); ss >> ldt; ss.str(""); ss << ldt; cout << ss.str() << endl; // "1400-Jan-01 00:00:00 UTC" ]]> NOTE: even though we sent in strings for min and max to the formatter, they are ignored because those special values construct to actual dates (as shown above). To illustrate the customization possibilities of periods and date_generators, we will use custom strings for months and weekdays (we will only use long names, is all lowercase, for readability), period delimiters, and the date_generator phrase elements. (continued from previous example) long_months(&month_names[0], &month_names[12]); string day_names[7] = { "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" }; vector long_days(&day_names[0], &day_names[7]); // custome date_generator phrases string dg_phrases[9] = { "1st", "2nd", "3rd", "4th", "5th", "final", "prior to", "following", "in" }; vector phrases(&dg_phrases[0], &dg_phrases[9]); // custom period formatter and parser period_formatter per_formatter(period_formatter::AS_OPEN_RANGE, " to ", "from ", " exclusive", " inclusive" ); period_parser per_parser(period_parser::AS_OPEN_RANGE, " to ", "from ", " exclusive" , "inclusive" ); // create date_facet and date_input_facet date_facet* date_output = new date_facet(); date_input_facet* date_input = new date_input_facet(); ss.imbue(locale(ss.getloc(), date_output)); ss.imbue(locale(ss.getloc(), date_input)); date_period dp(date(2005,3,1), days(31)); // month of march first_day_of_the_week_before d_gen(Monday); // defaults ss.str(""); ss << dp << "; " << d_gen; cout << ss.str() << endl; // "[2005-Mar-01/2005-Mar-31]; Mon before" // customize everything in the output facet date_output->long_month_names(long_months); date_output->long_weekday_names(long_days); date_output->date_gen_phrase_strings(phrases); date_output->period_formatter(per_formatter); // customize everything in the output facet date_input->long_month_names(long_months); date_input->long_weekday_names(long_days); date_input->date_gen_element_strings(phrases); date_input->period_parser(per_parser); // customize month, weekday and date formats date_output->format("%Y-%B-%d"); date_input->format("%Y-%B-%d"); date_output->month_format("%B"); // full name date_input->month_format("%B"); // full name date_output->weekday_format("%A"); // full name date_input->weekday_format("%A"); // full name ss.str("from 2005-february-01 to 2005-march-01 exclusive"); ss >> dp; ss.str("wednesday prior to"); ss >> d_gen; ss.str(""); ss << dp << " is the month of " << dp.begin().month(); cout << ss.str() << endl; ss.str(""); ss << "The " << d_gen << ' ' << dp.begin() << " is " << d_gen.get_date(dp.begin()); cout << ss.str() << endl; ]]>