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