io_tutorial.xml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
  3. "../../../tools/boostbook/dtd/boostbook.dtd">
  4. <!-- Copyright (c) 2005 CrystalClear Software, Inc.
  5. Subject to the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  7. -->
  8. <section id="date_time.io_tutorial"
  9. xmlns:xi="http://www.w3.org/2001/XInclude">
  10. <title>Date Time IO Tutorial</title>
  11. <bridgehead renderas="sect2">Date Time IO Tutorial</bridgehead>
  12. <link linkend="basic_use">Basic Use</link> |
  13. <link linkend="format_strings">Format Strings</link> |
  14. <link linkend="content_strings">Content Strings</link> |
  15. <link linkend="tut_sv">Special Values</link> |
  16. <link linkend="tut_dper">Date/Time Periods</link> |
  17. <link linkend="tut_dgen">Date Generators</link>
  18. <anchor id="basic_use" />
  19. <bridgehead renderas="sect4">Basic Use</bridgehead>
  20. <para>Facets are automatically imbued when operators '>>' and '&lt;&lt;' are called. The list of date_time objects that can be streamed are:</para>
  21. <bridgehead renderas="sect5">Gregorian</bridgehead>
  22. <para>
  23. <code>date</code>,
  24. <code>days</code>,
  25. <code>date_period</code>,
  26. <code>greg_month</code>,
  27. <code>greg_weekday</code>,
  28. <code>greg_year</code>,
  29. <code>partial_date</code>,
  30. <code>nth_day_of_the_week_in_month</code>,
  31. <code>first_day_of_the_week_in_month</code>,
  32. <code>last_day_of_the_week_in_month</code>,
  33. <code>first_day_of_the_week_after</code>,
  34. <code>first_day_of_the_week_before</code>
  35. </para>
  36. <bridgehead renderas="sect5">Posix_time</bridgehead>
  37. <para>
  38. <code>ptime</code>,
  39. <code>time_period</code>,
  40. <code>time_duration</code>
  41. </para>
  42. <bridgehead renderas="sect5">Local_time</bridgehead>
  43. <para>
  44. <code>local_date_time</code>
  45. </para>
  46. <para>
  47. The following example is of the basic use of the new IO code, utilizing all the defaults. (this example can be found in the <code>libs/date_time/example/tutorial</code> directory)
  48. </para>
  49. <programlisting>
  50. <![CDATA[
  51. date d(2004, Feb, 29);
  52. time_duration td(12,34,56,789);
  53. stringstream ss;
  54. ss << d << ' ' << td;
  55. ptime pt(not_a_date_time);
  56. cout << pt << endl; // "not-a-date-time"
  57. ss >> pt;
  58. cout << pt << endl; // "2004-Feb-29 12:34:56.000789"
  59. ss.str("");
  60. ss << pt << " EDT-05EDT,M4.1.0,M10.5.0";
  61. local_date_time ldt(not_a_date_time);
  62. ss >> ldt;
  63. cout << ldt << endl; // "2004-Feb-29 12:34:56.000789 EDT"
  64. ]]>
  65. </programlisting>
  66. <para>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 <link linkend="date_time.local_time.posix_time_zone">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).</para>
  67. <anchor id="format_strings" />
  68. <bridgehead renderas="sect4">Format Strings</bridgehead>
  69. <para>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.</para>
  70. (continued from previous example)
  71. <programlisting>
  72. <![CDATA[
  73. local_time_facet* output_facet = new local_time_facet();
  74. local_time_input_facet* input_facet = new local_time_input_facet();
  75. ss.imbue(locale(locale::classic(), output_facet));
  76. ss.imbue(locale(ss.getloc(), input_facet));
  77. output_facet->format("%a %b %d, %H:%M %z");
  78. ss.str("");
  79. ss << ldt;
  80. cout << ss.str() << endl; // "Sun Feb 29, 12:34 EDT"
  81. output_facet->format(local_time_facet::iso_time_format_specifier);
  82. ss.str("");
  83. ss << ldt;
  84. cout << ss.str() << endl; // "20040229T123456.000789-0500"
  85. output_facet->format(local_time_facet::iso_time_format_extended_specifier);
  86. ss.str("");
  87. ss << ldt;
  88. cout << ss.str() << endl; // "2004-02-29 12:34:56.000789-05:00"
  89. ]]>
  90. </programlisting>
  91. <para>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.</para>
  92. (continued from previous example)
  93. <programlisting>
  94. <![CDATA[
  95. // extra words in format
  96. string my_format("The extended ordinal time %Y-%jT%H:%M can also be \
  97. represented as %A %B %d, %Y");
  98. output_facet->format(my_format.c_str());
  99. input_facet->format(my_format.c_str());
  100. ss.str("");
  101. ss << ldt;
  102. cout << ss.str() << endl;
  103. // matching extra words in input
  104. ss.str("The extended ordinal time 2005-128T12:15 can also be \
  105. represented as Sunday May 08, 2005");
  106. ss >> ldt;
  107. cout << ldt << endl;
  108. ]]>
  109. </programlisting>
  110. <anchor id="content_strings" />
  111. <bridgehead renderas="sect4">Content Strings</bridgehead>
  112. <para>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.</para>
  113. <para>The default values for these are as follows:</para>
  114. <bridgehead renderas="sect5">Special values</bridgehead>
  115. <para>
  116. <code>not-a-date-time</code>,
  117. <code>-infinity</code>,
  118. <code>+infinity</code>,
  119. <code>minimum-date-time</code>,
  120. <code>maximum-date-time</code>
  121. </para>
  122. <bridgehead renderas="sect5">Months</bridgehead>
  123. <para>
  124. <code>English calendar and three letter abbreviations</code>
  125. </para>
  126. <bridgehead renderas="sect5">Weekdays</bridgehead>
  127. <para>
  128. <code>English calendar and three letter abbreviations</code>
  129. </para>
  130. <bridgehead renderas="sect5">Date generator phrase elements</bridgehead>
  131. <para>
  132. <code>first</code>,
  133. <code>second</code>,
  134. <code>third</code>,
  135. <code>fourth</code>,
  136. <code>fifth</code>,
  137. <code>last</code>,
  138. <code>before</code>,
  139. <code>after</code>,
  140. <code>of</code>
  141. </para>
  142. <para>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.</para>
  143. <bridgehead renderas="sect4">Content Strings</bridgehead>
  144. <para>To illustrate the customization possibilities we will use custom strings for months and weekdays (we will only use long names, is all lowercase, for this example).</para>
  145. (continued from previous example)
  146. <programlisting>
  147. <![CDATA[
  148. // set up the collections of custom strings.
  149. // only the full names are altered for the sake of brevity
  150. string month_names[12] = { "january", "february", "march",
  151. "april", "may", "june",
  152. "july", "august", "september",
  153. "october", "november", "december" };
  154. vector<string> long_months(&month_names[0], &month_names[12]);
  155. string day_names[7] = { "sunday", "monday", "tuesday", "wednesday",
  156. "thursday", "friday", "saturday" };
  157. vector<string> long_days(&day_names[0], &day_names[7]);
  158. // create date_facet and date_input_facet using all defaults
  159. date_facet* date_output = new date_facet();
  160. date_input_facet* date_input = new date_input_facet();
  161. ss.imbue(locale(ss.getloc(), date_output));
  162. ss.imbue(locale(ss.getloc(), date_input));
  163. // replace names in the output facet
  164. date_output->long_month_names(long_months);
  165. date_output->long_weekday_names(long_days);
  166. // replace names in the input facet
  167. date_input->long_month_names(long_months);
  168. date_input->long_weekday_names(long_days);
  169. // customize month, weekday and date formats
  170. date_output->format("%Y-%B-%d");
  171. date_input->format("%Y-%B-%d");
  172. date_output->month_format("%B"); // full name
  173. date_input->month_format("%B"); // full name
  174. date_output->weekday_format("%A"); // full name
  175. date_input->weekday_format("%A"); // full name
  176. ss.str("");
  177. ss << greg_month(3);
  178. cout << ss.str() << endl; // "march"
  179. ss.str("");
  180. ss << greg_weekday(3);
  181. cout << ss.str() << endl; // "tuesday"
  182. ss.str("");
  183. ss << date(2005,Jul,4);
  184. cout << ss.str() << endl; // "2005-july-04"
  185. ]]>
  186. </programlisting>
  187. <anchor id="tut_sv" />
  188. <bridgehead renderas="sect4">Special Values</bridgehead>
  189. <para>Customizing the input and output of special values is best done by creating a new special_values_parser and special_values_formatter. The new strings can be set at construction time (as in the example below).</para>
  190. (continued from previous example)
  191. <programlisting>
  192. <![CDATA[
  193. // reset the formats to defaults
  194. output_facet->format(local_time_facet::default_time_format);
  195. input_facet->format(local_time_input_facet::default_time_input_format);
  196. // create custom special_values parser and formatter objects
  197. // and add them to the facets
  198. string sv[5] = {"nadt","neg_inf", "pos_inf", "min_dt", "max_dt" };
  199. vector<string> sv_names(&sv[0], &sv[5]);
  200. special_values_parser sv_parser(sv_names.begin(), sv_names.end());
  201. special_values_formatter sv_formatter(sv_names.begin(), sv_names.end());
  202. output_facet->special_values_formatter(sv_formatter);
  203. input_facet->special_values_parser(sv_parser);
  204. ss.str("");
  205. ldt = local_date_time(not_a_date_time);
  206. ss << ldt;
  207. cout << ss.str() << endl; // "nadt"
  208. ss.str("min_dt");
  209. ss >> ldt;
  210. ss.str("");
  211. ss << ldt;
  212. cout << ss.str() << endl; // "1400-Jan-01 00:00:00 UTC"
  213. ]]>
  214. </programlisting>
  215. <para>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).</para>
  216. <anchor id="tut_dper" />
  217. <bridgehead renderas="sect4">Date/Time Periods</bridgehead>
  218. <para>Customizing the input and output of periods is best done by creating a new period_parser and period_formatter. The new strings can be set at construction time (as in the example below).</para>
  219. (continued from previous example)
  220. <programlisting>
  221. <![CDATA[
  222. // all formats set back to defaults (not shown for brevity)
  223. // create our date_period
  224. date_period dp(date(2005,Mar,1), days(31)); // month of march
  225. // custom period formatter and parser
  226. period_formatter per_formatter(period_formatter::AS_OPEN_RANGE,
  227. " to ", "from ", " exclusive", " inclusive" );
  228. period_parser per_parser(period_parser::AS_OPEN_RANGE,
  229. " to ", "from ", " exclusive" , "inclusive" );
  230. // default output
  231. ss.str("");
  232. ss << dp;
  233. cout << ss.str() << endl; // "[2005-Mar-01/2005-Mar-31]"
  234. // add out custom parser and formatter to the facets
  235. date_output->period_formatter(per_formatter);
  236. date_input->period_parser(per_parser);
  237. // custom output
  238. ss.str("");
  239. ss << dp;
  240. cout << ss.str() << endl; // "from 2005-Feb-01 to 2005-Apr-01 exclusive"
  241. ]]>
  242. </programlisting>
  243. <anchor id="tut_dgen" />
  244. <bridgehead renderas="sect4">Date Generators</bridgehead>
  245. <para>Customizing the input and output of date_generators is done by replacing the existing strings (in the facet) with new strings.</para>
  246. <para>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.</para>
  247. (continued from previous example)
  248. <programlisting>
  249. <![CDATA[
  250. // custom date_generator phrases
  251. string dg_phrases[9] = { "1st", "2nd", "3rd", "4th", "5th",
  252. "final", "prior to", "following", "in" };
  253. vector<string> phrases(&dg_phrases[0], &dg_phrases[9]);
  254. // create our date_generator
  255. first_day_of_the_week_before d_gen(Monday);
  256. // default output
  257. ss.str("");
  258. ss << d_gen;
  259. cout << ss.str() << endl; // "Mon before"
  260. // add our custom strings to the date facets
  261. date_output->date_gen_phrase_strings(phrases);
  262. date_input->date_gen_element_strings(phrases);
  263. // custom output
  264. ss.str("");
  265. ss << d_gen;
  266. cout << ss.str() << endl; // "Mon prior to"
  267. ]]>
  268. </programlisting>
  269. </section>