File: io_tutorial.xml

package info (click to toggle)
boost1.74 1.74.0-9
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 464,084 kB
  • sloc: cpp: 3,338,324; xml: 131,293; python: 33,088; ansic: 14,336; asm: 4,034; sh: 3,351; makefile: 1,193; perl: 1,036; yacc: 478; php: 212; ruby: 102; lisp: 24; sql: 13; csh: 6
file content (306 lines) | stat: -rw-r--r-- 12,564 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" 
"../../../tools/boostbook/dtd/boostbook.dtd">

<!-- Copyright (c) 2005 CrystalClear Software, Inc.
     Subject to the Boost Software License, Version 1.0. 
     (See accompanying file LICENSE_1_0.txt or  http://www.boost.org/LICENSE_1_0.txt)
-->

<section id="date_time.io_tutorial" 
  xmlns:xi="http://www.w3.org/2001/XInclude">
  <title>Date Time IO Tutorial</title>
  <bridgehead renderas="sect2">Date Time IO Tutorial</bridgehead>

  <link linkend="basic_use">Basic Use</link> |
  <link linkend="format_strings">Format Strings</link> |
  <link linkend="content_strings">Content Strings</link> |
  <link linkend="tut_sv">Special Values</link> |
  <link linkend="tut_dper">Date/Time Periods</link> |
  <link linkend="tut_dgen">Date Generators</link>
  
  <anchor id="basic_use" />
  <bridgehead renderas="sect4">Basic Use</bridgehead>
  <para>Facets are automatically imbued when operators '>>' and '&lt;&lt;' are called. The list of date_time objects that can be streamed are:</para>
  <bridgehead renderas="sect5">Gregorian</bridgehead>
  <para>
    <code>date</code>, 
    <code>days</code>, 
    <code>date_period</code>, 
    <code>greg_month</code>, 
    <code>greg_weekday</code>, 
    <code>greg_year</code>, 
    <code>partial_date</code>, 
    <code>nth_day_of_the_week_in_month</code>, 
    <code>first_day_of_the_week_in_month</code>, 
    <code>last_day_of_the_week_in_month</code>, 
    <code>first_day_of_the_week_after</code>, 
    <code>first_day_of_the_week_before</code>
  </para>
  <bridgehead renderas="sect5">Posix_time</bridgehead>
  <para>
    <code>ptime</code>, 
    <code>time_period</code>, 
    <code>time_duration</code>
  </para>
  <bridgehead renderas="sect5">Local_time</bridgehead>
  <para>
    <code>local_date_time</code>
  </para>
  
  <para>
    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)
  </para>
  <programlisting>
    <![CDATA[
  date d(2004, Feb, 29);
  time_duration td(12,34,56,789);
  stringstream ss;
  ss << d << ' ' << td;
  ptime pt(not_a_date_time);
  cout << pt << endl; // "not-a-date-time"
  ss >> 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"
    ]]>
  </programlisting>

  <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>

  <anchor id="format_strings" />
  <bridgehead renderas="sect4">Format Strings</bridgehead>
  <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>
  (continued from previous example)
  <programlisting>
    <![CDATA[
  local_time_facet* output_facet = new local_time_facet();
  local_time_input_facet* input_facet = new local_time_input_facet();
  ss.imbue(locale(locale::classic(), output_facet));
  ss.imbue(locale(ss.getloc(), input_facet));
  
  output_facet->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"
    ]]>
  </programlisting>

  <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>
  (continued from previous example)
  <programlisting>
    <![CDATA[
  // extra words in format
  string my_format("The extended ordinal time %Y-%jT%H:%M can also be \
  represented as %A %B %d, %Y");
  output_facet->format(my_format.c_str());
  input_facet->format(my_format.c_str());
  ss.str("");
  ss << ldt;
  cout << ss.str() << endl;

  // matching extra words in input 
  ss.str("The extended ordinal time 2005-128T12:15 can also be \
  represented as Sunday May 08, 2005");
  ss >> ldt;
  cout << ldt << endl;
    ]]>
  </programlisting>

  <anchor id="content_strings" />
  <bridgehead renderas="sect4">Content Strings</bridgehead>
  <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>
  <para>The default values for these are as follows:</para>
  <bridgehead renderas="sect5">Special values</bridgehead>
  <para>
    <code>not-a-date-time</code>, 
    <code>-infinity</code>, 
    <code>+infinity</code>, 
    <code>minimum-date-time</code>, 
    <code>maximum-date-time</code>
  </para>
  <bridgehead renderas="sect5">Months</bridgehead>
  <para>
    <code>English calendar and three letter abbreviations</code>
  </para>
  <bridgehead renderas="sect5">Weekdays</bridgehead>
  <para>
    <code>English calendar and three letter abbreviations</code>
  </para>
  <bridgehead renderas="sect5">Date generator phrase elements</bridgehead>
  <para>
    <code>first</code>, 
    <code>second</code>, 
    <code>third</code>, 
    <code>fourth</code>, 
    <code>fifth</code>, 
    <code>last</code>, 
    <code>before</code>, 
    <code>after</code>, 
    <code>of</code>
  </para>
  <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>

  <bridgehead renderas="sect4">Content Strings</bridgehead>
  <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>
  (continued from previous example)
  <programlisting>
    <![CDATA[
  // set up the collections of custom strings.
  // only the full names are altered for the sake of brevity
  string month_names[12] = { "january", "february", "march", 
                             "april", "may", "june", 
                             "july", "august", "september", 
                             "october", "november", "december" };
  vector<string> long_months(&month_names[0], &month_names[12]);
  string day_names[7] = { "sunday", "monday", "tuesday", "wednesday", 
                          "thursday", "friday", "saturday" };
  vector<string> long_days(&day_names[0], &day_names[7]);
  
  //  create date_facet and date_input_facet using all defaults
  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));

  // replace names in the output facet
  date_output->long_month_names(long_months);
  date_output->long_weekday_names(long_days);
  
  // replace names in the input facet
  date_input->long_month_names(long_months);
  date_input->long_weekday_names(long_days);
  
  // 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("");
  ss << greg_month(3);
  cout << ss.str() << endl; // "march"
  ss.str("");
  ss << greg_weekday(3);
  cout << ss.str() << endl; // "tuesday"
  ss.str("");
  ss << date(2005,Jul,4);
  cout << ss.str() << endl; // "2005-july-04"
    ]]>
  </programlisting>


  <anchor id="tut_sv" />
  <bridgehead renderas="sect4">Special Values</bridgehead>
  <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>
  (continued from previous example)
  <programlisting>
    <![CDATA[
  // reset the formats to defaults
  output_facet->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 objects
  // and add them to the facets
  string sv[5] = {"nadt","neg_inf", "pos_inf", "min_dt", "max_dt" };
  vector<string> 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"
    ]]>
  </programlisting>
  <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>


  <anchor id="tut_dper" />
  <bridgehead renderas="sect4">Date/Time Periods</bridgehead>
  <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>
  (continued from previous example)
  <programlisting>
    <![CDATA[
  // all formats set back to defaults (not shown for brevity)

  // create our date_period
  date_period dp(date(2005,Mar,1), days(31)); // month of march

  // 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" );
  
  // default output
  ss.str("");
  ss << dp;
  cout << ss.str() << endl; // "[2005-Mar-01/2005-Mar-31]"
 
  // add out custom parser and formatter to  the facets
  date_output->period_formatter(per_formatter);
  date_input->period_parser(per_parser);
  
  // custom output
  ss.str("");
  ss << dp;
  cout << ss.str() << endl; // "from 2005-Feb-01 to 2005-Apr-01 exclusive"
    ]]>
  </programlisting>

  <anchor id="tut_dgen" />
  <bridgehead renderas="sect4">Date Generators</bridgehead>
  <para>Customizing the input and output of date_generators is done by replacing the existing strings (in the facet) with new strings.</para>
  <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>
  (continued from previous example)
  <programlisting>
    <![CDATA[
  // custom date_generator phrases
  string dg_phrases[9] = { "1st", "2nd", "3rd", "4th", "5th", 
                           "final", "prior to", "following", "in" };
  vector<string> phrases(&dg_phrases[0], &dg_phrases[9]);

  // create our date_generator
  first_day_of_the_week_before d_gen(Monday);

  // default output
  ss.str("");
  ss << d_gen;
  cout << ss.str() << endl; // "Mon before"
 
  // add our custom strings to the date facets
  date_output->date_gen_phrase_strings(phrases);
  date_input->date_gen_element_strings(phrases);
  
  // custom output
  ss.str("");
  ss << d_gen;
  cout << ss.str() << endl; // "Mon prior to"
    ]]>
  </programlisting>

</section>