Chris@16
|
1 // (C) Copyright Howard Hinnant
|
Chris@16
|
2 // (C) Copyright 2010-2011 Vicente J. Botet Escriba
|
Chris@16
|
3 // Use, modification and distribution are subject to the Boost Software License,
|
Chris@16
|
4 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
5 // http://www.boost.org/LICENSE_1_0.txt).
|
Chris@16
|
6
|
Chris@16
|
7 //===-------------------------- locale ------------------------------------===//
|
Chris@16
|
8 //
|
Chris@16
|
9 // The LLVM Compiler Infrastructure
|
Chris@16
|
10 //
|
Chris@16
|
11 // This file is dual licensed under the MIT and the University of Illinois Open
|
Chris@16
|
12 // Source Licenses. See LICENSE.TXT for details.
|
Chris@16
|
13 //
|
Chris@16
|
14 //===----------------------------------------------------------------------===//
|
Chris@16
|
15
|
Chris@16
|
16 // This code was adapted by Vicente from Howard Hinnant's experimental work
|
Chris@16
|
17 // on chrono i/o to Boost and some functions from libc++/locale to emulate the missing time_get::get()
|
Chris@16
|
18
|
Chris@16
|
19 #ifndef BOOST_CHRONO_IO_TIME_POINT_IO_HPP
|
Chris@16
|
20 #define BOOST_CHRONO_IO_TIME_POINT_IO_HPP
|
Chris@16
|
21
|
Chris@16
|
22 #include <boost/chrono/io/time_point_put.hpp>
|
Chris@16
|
23 #include <boost/chrono/io/time_point_get.hpp>
|
Chris@16
|
24 #include <boost/chrono/io/duration_io.hpp>
|
Chris@16
|
25 #include <boost/chrono/io/ios_base_state.hpp>
|
Chris@16
|
26 #include <boost/chrono/io/utility/manip_base.hpp>
|
Chris@16
|
27 #include <boost/chrono/time_point.hpp>
|
Chris@16
|
28 #include <boost/chrono/clock_string.hpp>
|
Chris@16
|
29 #include <boost/chrono/round.hpp>
|
Chris@16
|
30 #include <boost/chrono/detail/scan_keyword.hpp>
|
Chris@16
|
31 #include <boost/static_assert.hpp>
|
Chris@16
|
32 #include <boost/detail/no_exceptions_support.hpp>
|
Chris@16
|
33 #include <cstring>
|
Chris@16
|
34 #include <locale>
|
Chris@16
|
35 #include <ctime>
|
Chris@16
|
36
|
Chris@16
|
37 #define BOOST_CHRONO_INTERNAL_TIMEGM \
|
Chris@16
|
38 ( defined BOOST_WINDOWS && ! defined(__CYGWIN__) ) \
|
Chris@101
|
39 || (defined(sun) || defined(__sun)) \
|
Chris@101
|
40 || (defined __IBMCPP__) \
|
Chris@101
|
41 || defined __ANDROID__ \
|
Chris@101
|
42 || defined __QNXNTO__ \
|
Chris@101
|
43 || (defined(_AIX) && defined __GNUC__)
|
Chris@16
|
44
|
Chris@16
|
45 #define BOOST_CHRONO_INTERNAL_GMTIME \
|
Chris@16
|
46 (defined BOOST_WINDOWS && ! defined(__CYGWIN__)) \
|
Chris@16
|
47 || ( (defined(sun) || defined(__sun)) && defined __GNUC__) \
|
Chris@101
|
48 || (defined __IBMCPP__) \
|
Chris@101
|
49 || defined __ANDROID__ \
|
Chris@101
|
50 || (defined(_AIX) && defined __GNUC__)
|
Chris@16
|
51
|
Chris@16
|
52 #define BOOST_CHRONO_USES_INTERNAL_TIME_GET
|
Chris@16
|
53
|
Chris@16
|
54 namespace boost
|
Chris@16
|
55 {
|
Chris@16
|
56 namespace chrono
|
Chris@16
|
57 {
|
Chris@16
|
58 typedef double fractional_seconds;
|
Chris@16
|
59 namespace detail
|
Chris@16
|
60 {
|
Chris@16
|
61
|
Chris@16
|
62
|
Chris@16
|
63 template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
|
Chris@16
|
64 struct time_get
|
Chris@16
|
65 {
|
Chris@16
|
66 std::time_get<CharT> const &that_;
|
Chris@16
|
67 time_get(std::time_get<CharT> const& that) : that_(that) {}
|
Chris@16
|
68
|
Chris@16
|
69 typedef std::time_get<CharT> facet;
|
Chris@16
|
70 typedef typename facet::iter_type iter_type;
|
Chris@16
|
71 typedef typename facet::char_type char_type;
|
Chris@16
|
72 typedef std::basic_string<char_type> string_type;
|
Chris@16
|
73
|
Chris@16
|
74 static int
|
Chris@16
|
75 get_up_to_n_digits(
|
Chris@16
|
76 InputIterator& b, InputIterator e,
|
Chris@16
|
77 std::ios_base::iostate& err,
|
Chris@16
|
78 const std::ctype<CharT>& ct,
|
Chris@16
|
79 int n)
|
Chris@16
|
80 {
|
Chris@16
|
81 // Precondition: n >= 1
|
Chris@16
|
82 if (b == e)
|
Chris@16
|
83 {
|
Chris@16
|
84 err |= std::ios_base::eofbit | std::ios_base::failbit;
|
Chris@16
|
85 return 0;
|
Chris@16
|
86 }
|
Chris@16
|
87 // get first digit
|
Chris@16
|
88 CharT c = *b;
|
Chris@16
|
89 if (!ct.is(std::ctype_base::digit, c))
|
Chris@16
|
90 {
|
Chris@16
|
91 err |= std::ios_base::failbit;
|
Chris@16
|
92 return 0;
|
Chris@16
|
93 }
|
Chris@16
|
94 int r = ct.narrow(c, 0) - '0';
|
Chris@16
|
95 for (++b, --n; b != e && n > 0; ++b, --n)
|
Chris@16
|
96 {
|
Chris@16
|
97 // get next digit
|
Chris@16
|
98 c = *b;
|
Chris@16
|
99 if (!ct.is(std::ctype_base::digit, c))
|
Chris@16
|
100 return r;
|
Chris@16
|
101 r = r * 10 + ct.narrow(c, 0) - '0';
|
Chris@16
|
102 }
|
Chris@16
|
103 if (b == e)
|
Chris@16
|
104 err |= std::ios_base::eofbit;
|
Chris@16
|
105 return r;
|
Chris@16
|
106 }
|
Chris@16
|
107
|
Chris@16
|
108
|
Chris@16
|
109 void get_day(
|
Chris@16
|
110 int& d,
|
Chris@16
|
111 iter_type& b, iter_type e,
|
Chris@16
|
112 std::ios_base::iostate& err,
|
Chris@16
|
113 const std::ctype<char_type>& ct) const
|
Chris@16
|
114 {
|
Chris@16
|
115 int t = get_up_to_n_digits(b, e, err, ct, 2);
|
Chris@16
|
116 if (!(err & std::ios_base::failbit) && 1 <= t && t <= 31)
|
Chris@16
|
117 d = t;
|
Chris@16
|
118 else
|
Chris@16
|
119 err |= std::ios_base::failbit;
|
Chris@16
|
120 }
|
Chris@16
|
121
|
Chris@16
|
122 void get_month(
|
Chris@16
|
123 int& m,
|
Chris@16
|
124 iter_type& b, iter_type e,
|
Chris@16
|
125 std::ios_base::iostate& err,
|
Chris@16
|
126 const std::ctype<char_type>& ct) const
|
Chris@16
|
127 {
|
Chris@16
|
128 int t = get_up_to_n_digits(b, e, err, ct, 2) - 1;
|
Chris@16
|
129 if (!(err & std::ios_base::failbit) && t <= 11)
|
Chris@16
|
130 m = t;
|
Chris@16
|
131 else
|
Chris@16
|
132 err |= std::ios_base::failbit;
|
Chris@16
|
133 }
|
Chris@16
|
134
|
Chris@16
|
135
|
Chris@16
|
136 void get_year4(int& y,
|
Chris@16
|
137 iter_type& b, iter_type e,
|
Chris@16
|
138 std::ios_base::iostate& err,
|
Chris@16
|
139 const std::ctype<char_type>& ct) const
|
Chris@16
|
140 {
|
Chris@16
|
141 int t = get_up_to_n_digits(b, e, err, ct, 4);
|
Chris@16
|
142 if (!(err & std::ios_base::failbit))
|
Chris@16
|
143 y = t - 1900;
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 void
|
Chris@16
|
147 get_hour(int& h,
|
Chris@16
|
148 iter_type& b, iter_type e,
|
Chris@16
|
149 std::ios_base::iostate& err,
|
Chris@16
|
150 const std::ctype<char_type>& ct) const
|
Chris@16
|
151 {
|
Chris@16
|
152 int t = get_up_to_n_digits(b, e, err, ct, 2);
|
Chris@16
|
153 if (!(err & std::ios_base::failbit) && t <= 23)
|
Chris@16
|
154 h = t;
|
Chris@16
|
155 else
|
Chris@16
|
156 err |= std::ios_base::failbit;
|
Chris@16
|
157 }
|
Chris@16
|
158
|
Chris@16
|
159 void
|
Chris@16
|
160 get_minute(int& m,
|
Chris@16
|
161 iter_type& b, iter_type e,
|
Chris@16
|
162 std::ios_base::iostate& err,
|
Chris@16
|
163 const std::ctype<char_type>& ct) const
|
Chris@16
|
164 {
|
Chris@16
|
165 int t = get_up_to_n_digits(b, e, err, ct, 2);
|
Chris@16
|
166 if (!(err & std::ios_base::failbit) && t <= 59)
|
Chris@16
|
167 m = t;
|
Chris@16
|
168 else
|
Chris@16
|
169 err |= std::ios_base::failbit;
|
Chris@16
|
170 }
|
Chris@16
|
171
|
Chris@16
|
172 void get_second(int& s,
|
Chris@16
|
173 iter_type& b, iter_type e,
|
Chris@16
|
174 std::ios_base::iostate& err,
|
Chris@16
|
175 const std::ctype<char_type>& ct) const
|
Chris@16
|
176 {
|
Chris@16
|
177 int t = get_up_to_n_digits(b, e, err, ct, 2);
|
Chris@16
|
178 if (!(err & std::ios_base::failbit) && t <= 60)
|
Chris@16
|
179 s = t;
|
Chris@16
|
180 else
|
Chris@16
|
181 err |= std::ios_base::failbit;
|
Chris@16
|
182 }
|
Chris@16
|
183
|
Chris@16
|
184 void get_white_space(iter_type& b, iter_type e,
|
Chris@16
|
185 std::ios_base::iostate& err,
|
Chris@16
|
186 const std::ctype<char_type>& ct) const
|
Chris@16
|
187 {
|
Chris@16
|
188 for (; b != e && ct.is(std::ctype_base::space, *b); ++b)
|
Chris@16
|
189 ;
|
Chris@16
|
190 if (b == e)
|
Chris@16
|
191 err |= std::ios_base::eofbit;
|
Chris@16
|
192 }
|
Chris@16
|
193
|
Chris@16
|
194 void get_12_hour(int& h,
|
Chris@16
|
195 iter_type& b, iter_type e,
|
Chris@16
|
196 std::ios_base::iostate& err,
|
Chris@16
|
197 const std::ctype<char_type>& ct) const
|
Chris@16
|
198 {
|
Chris@16
|
199 int t = get_up_to_n_digits(b, e, err, ct, 2);
|
Chris@16
|
200 if (!(err & std::ios_base::failbit) && 1 <= t && t <= 12)
|
Chris@16
|
201 h = t;
|
Chris@16
|
202 else
|
Chris@16
|
203 err |= std::ios_base::failbit;
|
Chris@16
|
204 }
|
Chris@16
|
205
|
Chris@16
|
206 void get_percent(iter_type& b, iter_type e,
|
Chris@16
|
207 std::ios_base::iostate& err,
|
Chris@16
|
208 const std::ctype<char_type>& ct) const
|
Chris@16
|
209 {
|
Chris@16
|
210 if (b == e)
|
Chris@16
|
211 {
|
Chris@16
|
212 err |= std::ios_base::eofbit | std::ios_base::failbit;
|
Chris@16
|
213 return;
|
Chris@16
|
214 }
|
Chris@16
|
215 if (ct.narrow(*b, 0) != '%')
|
Chris@16
|
216 err |= std::ios_base::failbit;
|
Chris@16
|
217 else if(++b == e)
|
Chris@16
|
218 err |= std::ios_base::eofbit;
|
Chris@16
|
219 }
|
Chris@16
|
220
|
Chris@16
|
221 void get_day_year_num(int& d,
|
Chris@16
|
222 iter_type& b, iter_type e,
|
Chris@16
|
223 std::ios_base::iostate& err,
|
Chris@16
|
224 const std::ctype<char_type>& ct) const
|
Chris@16
|
225 {
|
Chris@16
|
226 int t = get_up_to_n_digits(b, e, err, ct, 3);
|
Chris@16
|
227 if (!(err & std::ios_base::failbit) && t <= 365)
|
Chris@16
|
228 d = t;
|
Chris@16
|
229 else
|
Chris@16
|
230 err |= std::ios_base::failbit;
|
Chris@16
|
231 }
|
Chris@16
|
232
|
Chris@16
|
233 void
|
Chris@16
|
234 get_weekday(int& w,
|
Chris@16
|
235 iter_type& b, iter_type e,
|
Chris@16
|
236 std::ios_base::iostate& err,
|
Chris@16
|
237 const std::ctype<char_type>& ct) const
|
Chris@16
|
238 {
|
Chris@16
|
239 int t = get_up_to_n_digits(b, e, err, ct, 1);
|
Chris@16
|
240 if (!(err & std::ios_base::failbit) && t <= 6)
|
Chris@16
|
241 w = t;
|
Chris@16
|
242 else
|
Chris@16
|
243 err |= std::ios_base::failbit;
|
Chris@16
|
244 }
|
Chris@16
|
245 #if 0
|
Chris@16
|
246
|
Chris@16
|
247 void
|
Chris@16
|
248 get_am_pm(int& h,
|
Chris@16
|
249 iter_type& b, iter_type e,
|
Chris@16
|
250 std::ios_base::iostate& err,
|
Chris@16
|
251 const std::ctype<char_type>& ct) const
|
Chris@16
|
252 {
|
Chris@16
|
253 const string_type* ap = am_pm();
|
Chris@16
|
254 if (ap[0].size() + ap[1].size() == 0)
|
Chris@16
|
255 {
|
Chris@16
|
256 err |= ios_base::failbit;
|
Chris@16
|
257 return;
|
Chris@16
|
258 }
|
Chris@16
|
259 ptrdiff_t i = detail::scan_keyword(b, e, ap, ap+2, ct, err, false) - ap;
|
Chris@16
|
260 if (i == 0 && h == 12)
|
Chris@16
|
261 h = 0;
|
Chris@16
|
262 else if (i == 1 && h < 12)
|
Chris@16
|
263 h += 12;
|
Chris@16
|
264 }
|
Chris@16
|
265
|
Chris@16
|
266 #endif
|
Chris@16
|
267
|
Chris@16
|
268 InputIterator get(
|
Chris@16
|
269 iter_type b, iter_type e,
|
Chris@16
|
270 std::ios_base& iob,
|
Chris@16
|
271 std::ios_base::iostate& err,
|
Chris@16
|
272 std::tm* tm,
|
Chris@16
|
273 char fmt, char) const
|
Chris@16
|
274 {
|
Chris@16
|
275 err = std::ios_base::goodbit;
|
Chris@16
|
276 const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(iob.getloc());
|
Chris@16
|
277
|
Chris@16
|
278 switch (fmt)
|
Chris@16
|
279 {
|
Chris@16
|
280 case 'a':
|
Chris@16
|
281 case 'A':
|
Chris@16
|
282 {
|
Chris@16
|
283 std::tm tm2;
|
Chris@16
|
284 std::memset(&tm2, 0, sizeof(std::tm));
|
Chris@16
|
285 that_.get_weekday(b, e, iob, err, &tm2);
|
Chris@16
|
286 //tm->tm_wday = tm2.tm_wday;
|
Chris@16
|
287 }
|
Chris@16
|
288 break;
|
Chris@16
|
289 case 'b':
|
Chris@16
|
290 case 'B':
|
Chris@16
|
291 case 'h':
|
Chris@16
|
292 {
|
Chris@16
|
293 std::tm tm2;
|
Chris@16
|
294 std::memset(&tm2, 0, sizeof(std::tm));
|
Chris@16
|
295 that_.get_monthname(b, e, iob, err, &tm2);
|
Chris@16
|
296 //tm->tm_mon = tm2.tm_mon;
|
Chris@16
|
297 }
|
Chris@16
|
298 break;
|
Chris@16
|
299 // case 'c':
|
Chris@16
|
300 // {
|
Chris@16
|
301 // const string_type& fm = c();
|
Chris@16
|
302 // b = get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size());
|
Chris@16
|
303 // }
|
Chris@16
|
304 // break;
|
Chris@16
|
305 case 'd':
|
Chris@16
|
306 case 'e':
|
Chris@16
|
307 get_day(tm->tm_mday, b, e, err, ct);
|
Chris@16
|
308 break;
|
Chris@16
|
309 case 'D':
|
Chris@16
|
310 {
|
Chris@16
|
311 const char_type fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
|
Chris@16
|
312 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
|
Chris@16
|
313 }
|
Chris@16
|
314 break;
|
Chris@16
|
315 case 'F':
|
Chris@16
|
316 {
|
Chris@16
|
317 const char_type fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
|
Chris@16
|
318 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
|
Chris@16
|
319 }
|
Chris@16
|
320 break;
|
Chris@16
|
321 case 'H':
|
Chris@16
|
322 get_hour(tm->tm_hour, b, e, err, ct);
|
Chris@16
|
323 break;
|
Chris@16
|
324 case 'I':
|
Chris@16
|
325 get_12_hour(tm->tm_hour, b, e, err, ct);
|
Chris@16
|
326 break;
|
Chris@16
|
327 case 'j':
|
Chris@16
|
328 get_day_year_num(tm->tm_yday, b, e, err, ct);
|
Chris@16
|
329 break;
|
Chris@16
|
330 case 'm':
|
Chris@16
|
331 get_month(tm->tm_mon, b, e, err, ct);
|
Chris@16
|
332 break;
|
Chris@16
|
333 case 'M':
|
Chris@16
|
334 get_minute(tm->tm_min, b, e, err, ct);
|
Chris@16
|
335 break;
|
Chris@16
|
336 case 'n':
|
Chris@16
|
337 case 't':
|
Chris@16
|
338 get_white_space(b, e, err, ct);
|
Chris@16
|
339 break;
|
Chris@16
|
340 // case 'p':
|
Chris@16
|
341 // get_am_pm(tm->tm_hour, b, e, err, ct);
|
Chris@16
|
342 // break;
|
Chris@16
|
343 case 'r':
|
Chris@16
|
344 {
|
Chris@16
|
345 const char_type fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
|
Chris@16
|
346 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
|
Chris@16
|
347 }
|
Chris@16
|
348 break;
|
Chris@16
|
349 case 'R':
|
Chris@16
|
350 {
|
Chris@16
|
351 const char_type fm[] = {'%', 'H', ':', '%', 'M'};
|
Chris@16
|
352 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
|
Chris@16
|
353 }
|
Chris@16
|
354 break;
|
Chris@16
|
355 case 'S':
|
Chris@16
|
356 get_second(tm->tm_sec, b, e, err, ct);
|
Chris@16
|
357 break;
|
Chris@16
|
358 case 'T':
|
Chris@16
|
359 {
|
Chris@16
|
360 const char_type fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
|
Chris@16
|
361 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
|
Chris@16
|
362 }
|
Chris@16
|
363 break;
|
Chris@16
|
364 case 'w':
|
Chris@16
|
365 {
|
Chris@16
|
366 get_weekday(tm->tm_wday, b, e, err, ct);
|
Chris@16
|
367 }
|
Chris@16
|
368 break;
|
Chris@16
|
369 case 'x':
|
Chris@16
|
370 return that_.get_date(b, e, iob, err, tm);
|
Chris@16
|
371 // case 'X':
|
Chris@16
|
372 // return that_.get_time(b, e, iob, err, tm);
|
Chris@16
|
373 // {
|
Chris@16
|
374 // const string_type& fm = X();
|
Chris@16
|
375 // b = that_.get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size());
|
Chris@16
|
376 // }
|
Chris@16
|
377 // break;
|
Chris@16
|
378 // case 'y':
|
Chris@16
|
379 // get_year(tm->tm_year, b, e, err, ct);
|
Chris@16
|
380 break;
|
Chris@16
|
381 case 'Y':
|
Chris@16
|
382 get_year4(tm->tm_year, b, e, err, ct);
|
Chris@16
|
383 break;
|
Chris@16
|
384 case '%':
|
Chris@16
|
385 get_percent(b, e, err, ct);
|
Chris@16
|
386 break;
|
Chris@16
|
387 default:
|
Chris@16
|
388 err |= std::ios_base::failbit;
|
Chris@16
|
389 }
|
Chris@16
|
390 return b;
|
Chris@16
|
391 }
|
Chris@16
|
392
|
Chris@16
|
393
|
Chris@16
|
394 InputIterator get(
|
Chris@16
|
395 iter_type b, iter_type e,
|
Chris@16
|
396 std::ios_base& iob,
|
Chris@16
|
397 std::ios_base::iostate& err, std::tm* tm,
|
Chris@16
|
398 const char_type* fmtb, const char_type* fmte) const
|
Chris@16
|
399 {
|
Chris@16
|
400 const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(iob.getloc());
|
Chris@16
|
401 err = std::ios_base::goodbit;
|
Chris@16
|
402 while (fmtb != fmte && err == std::ios_base::goodbit)
|
Chris@16
|
403 {
|
Chris@16
|
404 if (b == e)
|
Chris@16
|
405 {
|
Chris@16
|
406 err = std::ios_base::failbit;
|
Chris@16
|
407 break;
|
Chris@16
|
408 }
|
Chris@16
|
409 if (ct.narrow(*fmtb, 0) == '%')
|
Chris@16
|
410 {
|
Chris@16
|
411 if (++fmtb == fmte)
|
Chris@16
|
412 {
|
Chris@16
|
413 err = std::ios_base::failbit;
|
Chris@16
|
414 break;
|
Chris@16
|
415 }
|
Chris@16
|
416 char cmd = ct.narrow(*fmtb, 0);
|
Chris@16
|
417 char opt = '\0';
|
Chris@16
|
418 if (cmd == 'E' || cmd == '0')
|
Chris@16
|
419 {
|
Chris@16
|
420 if (++fmtb == fmte)
|
Chris@16
|
421 {
|
Chris@16
|
422 err = std::ios_base::failbit;
|
Chris@16
|
423 break;
|
Chris@16
|
424 }
|
Chris@16
|
425 opt = cmd;
|
Chris@16
|
426 cmd = ct.narrow(*fmtb, 0);
|
Chris@16
|
427 }
|
Chris@16
|
428 b = get(b, e, iob, err, tm, cmd, opt);
|
Chris@16
|
429 ++fmtb;
|
Chris@16
|
430 }
|
Chris@16
|
431 else if (ct.is(std::ctype_base::space, *fmtb))
|
Chris@16
|
432 {
|
Chris@16
|
433 for (++fmtb; fmtb != fmte && ct.is(std::ctype_base::space, *fmtb); ++fmtb)
|
Chris@16
|
434 ;
|
Chris@16
|
435 for ( ; b != e && ct.is(std::ctype_base::space, *b); ++b)
|
Chris@16
|
436 ;
|
Chris@16
|
437 }
|
Chris@16
|
438 else if (ct.toupper(*b) == ct.toupper(*fmtb))
|
Chris@16
|
439 {
|
Chris@16
|
440 ++b;
|
Chris@16
|
441 ++fmtb;
|
Chris@16
|
442 }
|
Chris@16
|
443 else
|
Chris@16
|
444 err = std::ios_base::failbit;
|
Chris@16
|
445 }
|
Chris@16
|
446 if (b == e)
|
Chris@16
|
447 err |= std::ios_base::eofbit;
|
Chris@16
|
448 return b;
|
Chris@16
|
449 }
|
Chris@16
|
450
|
Chris@16
|
451 };
|
Chris@16
|
452
|
Chris@16
|
453
|
Chris@16
|
454 template <class CharT>
|
Chris@16
|
455 class time_manip: public manip<time_manip<CharT> >
|
Chris@16
|
456 {
|
Chris@16
|
457 std::basic_string<CharT> fmt_;
|
Chris@16
|
458 timezone tz_;
|
Chris@16
|
459 public:
|
Chris@16
|
460
|
Chris@16
|
461 time_manip(timezone tz, std::basic_string<CharT> fmt)
|
Chris@16
|
462 // todo move semantics
|
Chris@16
|
463 :
|
Chris@16
|
464 fmt_(fmt), tz_(tz)
|
Chris@16
|
465 {
|
Chris@16
|
466 }
|
Chris@16
|
467
|
Chris@16
|
468 /**
|
Chris@16
|
469 * Change the timezone and time format ios state;
|
Chris@16
|
470 */
|
Chris@16
|
471 void operator()(std::ios_base &ios) const
|
Chris@16
|
472 {
|
Chris@16
|
473 set_time_fmt<CharT> (ios, fmt_);
|
Chris@16
|
474 set_timezone(ios, tz_);
|
Chris@16
|
475 }
|
Chris@16
|
476 };
|
Chris@16
|
477
|
Chris@16
|
478 class time_man: public manip<time_man>
|
Chris@16
|
479 {
|
Chris@16
|
480 timezone tz_;
|
Chris@16
|
481 public:
|
Chris@16
|
482
|
Chris@16
|
483 time_man(timezone tz)
|
Chris@16
|
484 // todo move semantics
|
Chris@16
|
485 :
|
Chris@16
|
486 tz_(tz)
|
Chris@16
|
487 {
|
Chris@16
|
488 }
|
Chris@16
|
489
|
Chris@16
|
490 /**
|
Chris@16
|
491 * Change the timezone and time format ios state;
|
Chris@16
|
492 */
|
Chris@16
|
493 void operator()(std::ios_base &ios) const
|
Chris@16
|
494 {
|
Chris@16
|
495 //set_time_fmt<typename out_stream::char_type>(ios, "");
|
Chris@16
|
496 set_timezone(ios, tz_);
|
Chris@16
|
497 }
|
Chris@16
|
498 };
|
Chris@16
|
499
|
Chris@16
|
500 }
|
Chris@16
|
501
|
Chris@16
|
502 template <class CharT>
|
Chris@16
|
503 inline detail::time_manip<CharT> time_fmt(timezone tz, const CharT* fmt)
|
Chris@16
|
504 {
|
Chris@16
|
505 return detail::time_manip<CharT>(tz, fmt);
|
Chris@16
|
506 }
|
Chris@16
|
507
|
Chris@16
|
508 template <class CharT>
|
Chris@16
|
509 inline detail::time_manip<CharT> time_fmt(timezone tz, std::basic_string<CharT> fmt)
|
Chris@16
|
510 {
|
Chris@16
|
511 // todo move semantics
|
Chris@16
|
512 return detail::time_manip<CharT>(tz, fmt);
|
Chris@16
|
513 }
|
Chris@16
|
514
|
Chris@16
|
515 inline detail::time_man time_fmt(timezone f)
|
Chris@16
|
516 {
|
Chris@16
|
517 return detail::time_man(f);
|
Chris@16
|
518 }
|
Chris@16
|
519
|
Chris@16
|
520 /**
|
Chris@16
|
521 * time_fmt_io_saver i/o saver.
|
Chris@16
|
522 *
|
Chris@16
|
523 * See Boost.IO i/o state savers for a motivating compression.
|
Chris@16
|
524 */
|
Chris@16
|
525 template <typename CharT = char, typename Traits = std::char_traits<CharT> >
|
Chris@16
|
526 struct time_fmt_io_saver
|
Chris@16
|
527 {
|
Chris@16
|
528
|
Chris@16
|
529 //! the type of the state to restore
|
Chris@101
|
530 //typedef std::basic_ostream<CharT, Traits> state_type;
|
Chris@101
|
531 typedef std::ios_base state_type;
|
Chris@101
|
532
|
Chris@16
|
533 //! the type of aspect to save
|
Chris@16
|
534 typedef std::basic_string<CharT, Traits> aspect_type;
|
Chris@16
|
535
|
Chris@16
|
536 /**
|
Chris@16
|
537 * Explicit construction from an i/o stream.
|
Chris@16
|
538 *
|
Chris@16
|
539 * Store a reference to the i/o stream and the value of the associated @c time format .
|
Chris@16
|
540 */
|
Chris@16
|
541 explicit time_fmt_io_saver(state_type &s) :
|
Chris@101
|
542 s_save_(s), a_save_(get_time_fmt<CharT>(s_save_))
|
Chris@16
|
543 {
|
Chris@16
|
544 }
|
Chris@16
|
545
|
Chris@16
|
546 /**
|
Chris@16
|
547 * Construction from an i/o stream and a @c time format to restore.
|
Chris@16
|
548 *
|
Chris@16
|
549 * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter.
|
Chris@16
|
550 */
|
Chris@16
|
551 time_fmt_io_saver(state_type &s, aspect_type new_value) :
|
Chris@101
|
552 s_save_(s), a_save_(get_time_fmt<CharT>(s_save_))
|
Chris@16
|
553 {
|
Chris@101
|
554 set_time_fmt(s_save_, new_value);
|
Chris@16
|
555 }
|
Chris@16
|
556
|
Chris@16
|
557 /**
|
Chris@16
|
558 * Destructor.
|
Chris@16
|
559 *
|
Chris@16
|
560 * Restores the i/o stream with the format to be restored.
|
Chris@16
|
561 */
|
Chris@16
|
562 ~time_fmt_io_saver()
|
Chris@16
|
563 {
|
Chris@16
|
564 this->restore();
|
Chris@16
|
565 }
|
Chris@16
|
566
|
Chris@16
|
567 /**
|
Chris@16
|
568 * Restores the i/o stream with the time format to be restored.
|
Chris@16
|
569 */
|
Chris@16
|
570 void restore()
|
Chris@16
|
571 {
|
Chris@101
|
572 set_time_fmt(s_save_, a_save_);
|
Chris@16
|
573 }
|
Chris@16
|
574 private:
|
Chris@16
|
575 state_type& s_save_;
|
Chris@16
|
576 aspect_type a_save_;
|
Chris@16
|
577 };
|
Chris@16
|
578
|
Chris@16
|
579 /**
|
Chris@16
|
580 * timezone_io_saver i/o saver.
|
Chris@16
|
581 *
|
Chris@16
|
582 * See Boost.IO i/o state savers for a motivating compression.
|
Chris@16
|
583 */
|
Chris@16
|
584 struct timezone_io_saver
|
Chris@16
|
585 {
|
Chris@16
|
586
|
Chris@16
|
587 //! the type of the state to restore
|
Chris@16
|
588 typedef std::ios_base state_type;
|
Chris@16
|
589 //! the type of aspect to save
|
Chris@16
|
590 typedef timezone aspect_type;
|
Chris@16
|
591
|
Chris@16
|
592 /**
|
Chris@16
|
593 * Explicit construction from an i/o stream.
|
Chris@16
|
594 *
|
Chris@16
|
595 * Store a reference to the i/o stream and the value of the associated @c timezone.
|
Chris@16
|
596 */
|
Chris@16
|
597 explicit timezone_io_saver(state_type &s) :
|
Chris@16
|
598 s_save_(s), a_save_(get_timezone(s_save_))
|
Chris@16
|
599 {
|
Chris@16
|
600 }
|
Chris@16
|
601
|
Chris@16
|
602 /**
|
Chris@16
|
603 * Construction from an i/o stream and a @c timezone to restore.
|
Chris@16
|
604 *
|
Chris@16
|
605 * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter.
|
Chris@16
|
606 */
|
Chris@16
|
607 timezone_io_saver(state_type &s, aspect_type new_value) :
|
Chris@101
|
608 s_save_(s), a_save_(get_timezone(s_save_))
|
Chris@16
|
609 {
|
Chris@101
|
610 set_timezone(s_save_, new_value);
|
Chris@16
|
611 }
|
Chris@16
|
612
|
Chris@16
|
613 /**
|
Chris@16
|
614 * Destructor.
|
Chris@16
|
615 *
|
Chris@16
|
616 * Restores the i/o stream with the format to be restored.
|
Chris@16
|
617 */
|
Chris@16
|
618 ~timezone_io_saver()
|
Chris@16
|
619 {
|
Chris@16
|
620 this->restore();
|
Chris@16
|
621 }
|
Chris@16
|
622
|
Chris@16
|
623 /**
|
Chris@16
|
624 * Restores the i/o stream with the timezone to be restored.
|
Chris@16
|
625 */
|
Chris@16
|
626 void restore()
|
Chris@16
|
627 {
|
Chris@16
|
628 set_timezone(s_save_, a_save_);
|
Chris@16
|
629 }
|
Chris@16
|
630 private:
|
Chris@16
|
631 timezone_io_saver& operator=(timezone_io_saver const& rhs) ;
|
Chris@16
|
632
|
Chris@16
|
633 state_type& s_save_;
|
Chris@16
|
634 aspect_type a_save_;
|
Chris@16
|
635 };
|
Chris@16
|
636
|
Chris@16
|
637 /**
|
Chris@16
|
638 *
|
Chris@16
|
639 * @param os
|
Chris@16
|
640 * @param tp
|
Chris@16
|
641 * @Effects Behaves as a formatted output function. After constructing a @c sentry object, if the @ sentry
|
Chris@16
|
642 * converts to true, calls to @c facet.put(os,os,os.fill(),tp) where @c facet is the @c time_point_put<CharT>
|
Chris@16
|
643 * facet associated to @c os or a new created instance of the default @c time_point_put<CharT> facet.
|
Chris@16
|
644 * @return @c os.
|
Chris@16
|
645 */
|
Chris@16
|
646 template <class CharT, class Traits, class Clock, class Duration>
|
Chris@16
|
647 std::basic_ostream<CharT, Traits>&
|
Chris@16
|
648 operator<<(std::basic_ostream<CharT, Traits>& os, const time_point<Clock, Duration>& tp)
|
Chris@16
|
649 {
|
Chris@16
|
650
|
Chris@16
|
651 bool failed = false;
|
Chris@16
|
652 BOOST_TRY
|
Chris@16
|
653 {
|
Chris@16
|
654 std::ios_base::iostate err = std::ios_base::goodbit;
|
Chris@16
|
655 BOOST_TRY
|
Chris@16
|
656 {
|
Chris@16
|
657 typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
|
Chris@16
|
658 if (bool(opfx))
|
Chris@16
|
659 {
|
Chris@16
|
660 if (!std::has_facet<time_point_put<CharT> >(os.getloc()))
|
Chris@16
|
661 {
|
Chris@16
|
662 if (time_point_put<CharT> ().put(os, os, os.fill(), tp) .failed())
|
Chris@16
|
663 {
|
Chris@16
|
664 err = std::ios_base::badbit;
|
Chris@16
|
665 }
|
Chris@16
|
666 }
|
Chris@16
|
667 else
|
Chris@16
|
668 {
|
Chris@16
|
669 if (std::use_facet<time_point_put<CharT> >(os.getloc()) .put(os, os, os.fill(), tp).failed())
|
Chris@16
|
670 {
|
Chris@16
|
671 err = std::ios_base::badbit;
|
Chris@16
|
672 }
|
Chris@16
|
673 }
|
Chris@16
|
674 os.width(0);
|
Chris@16
|
675 }
|
Chris@16
|
676 }
|
Chris@16
|
677 BOOST_CATCH (...)
|
Chris@16
|
678 {
|
Chris@16
|
679 bool flag = false;
|
Chris@16
|
680 BOOST_TRY
|
Chris@16
|
681 {
|
Chris@16
|
682 os.setstate(std::ios_base::failbit);
|
Chris@16
|
683 }
|
Chris@16
|
684 BOOST_CATCH (std::ios_base::failure )
|
Chris@16
|
685 {
|
Chris@16
|
686 flag = true;
|
Chris@16
|
687 }
|
Chris@16
|
688 BOOST_CATCH_END
|
Chris@16
|
689 if (flag) throw;
|
Chris@16
|
690 }
|
Chris@16
|
691 BOOST_CATCH_END
|
Chris@16
|
692 if (err) os.setstate(err);
|
Chris@16
|
693 return os;
|
Chris@16
|
694 }
|
Chris@16
|
695 BOOST_CATCH (...)
|
Chris@16
|
696 {
|
Chris@16
|
697 failed = true;
|
Chris@16
|
698 }
|
Chris@16
|
699 BOOST_CATCH_END
|
Chris@16
|
700 if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
|
Chris@16
|
701 return os;
|
Chris@16
|
702 }
|
Chris@16
|
703
|
Chris@16
|
704 template <class CharT, class Traits, class Clock, class Duration>
|
Chris@16
|
705 std::basic_istream<CharT, Traits>&
|
Chris@16
|
706 operator>>(std::basic_istream<CharT, Traits>& is, time_point<Clock, Duration>& tp)
|
Chris@16
|
707 {
|
Chris@16
|
708 std::ios_base::iostate err = std::ios_base::goodbit;
|
Chris@16
|
709
|
Chris@16
|
710 BOOST_TRY
|
Chris@16
|
711 {
|
Chris@16
|
712 typename std::basic_istream<CharT, Traits>::sentry ipfx(is);
|
Chris@16
|
713 if (bool(ipfx))
|
Chris@16
|
714 {
|
Chris@16
|
715 if (!std::has_facet<time_point_get<CharT> >(is.getloc()))
|
Chris@16
|
716 {
|
Chris@16
|
717 time_point_get<CharT> ().get(is, std::istreambuf_iterator<CharT, Traits>(), is, err, tp);
|
Chris@16
|
718 }
|
Chris@16
|
719 else
|
Chris@16
|
720 {
|
Chris@16
|
721 std::use_facet<time_point_get<CharT> >(is.getloc()).get(is, std::istreambuf_iterator<CharT, Traits>(), is,
|
Chris@16
|
722 err, tp);
|
Chris@16
|
723 }
|
Chris@16
|
724 }
|
Chris@16
|
725 }
|
Chris@16
|
726 BOOST_CATCH (...)
|
Chris@16
|
727 {
|
Chris@16
|
728 bool flag = false;
|
Chris@16
|
729 BOOST_TRY
|
Chris@16
|
730 {
|
Chris@16
|
731 is.setstate(std::ios_base::failbit);
|
Chris@16
|
732 }
|
Chris@16
|
733 BOOST_CATCH (std::ios_base::failure )
|
Chris@16
|
734 {
|
Chris@16
|
735 flag = true;
|
Chris@16
|
736 }
|
Chris@16
|
737 BOOST_CATCH_END
|
Chris@16
|
738 if (flag) throw;
|
Chris@16
|
739 }
|
Chris@16
|
740 BOOST_CATCH_END
|
Chris@16
|
741 if (err) is.setstate(err);
|
Chris@16
|
742 return is;
|
Chris@16
|
743 }
|
Chris@16
|
744
|
Chris@16
|
745
|
Chris@16
|
746 namespace detail
|
Chris@16
|
747 {
|
Chris@16
|
748
|
Chris@101
|
749 //#if BOOST_CHRONO_INTERNAL_TIMEGM
|
Chris@101
|
750
|
Chris@16
|
751 inline int32_t is_leap(int32_t year)
|
Chris@16
|
752 {
|
Chris@16
|
753 if(year % 400 == 0)
|
Chris@16
|
754 return 1;
|
Chris@16
|
755 if(year % 100 == 0)
|
Chris@16
|
756 return 0;
|
Chris@16
|
757 if(year % 4 == 0)
|
Chris@16
|
758 return 1;
|
Chris@16
|
759 return 0;
|
Chris@16
|
760 }
|
Chris@16
|
761 inline int32_t days_from_0(int32_t year)
|
Chris@16
|
762 {
|
Chris@16
|
763 year--;
|
Chris@16
|
764 return 365 * year + (year / 400) - (year/100) + (year / 4);
|
Chris@16
|
765 }
|
Chris@16
|
766 inline int32_t days_from_1970(int32_t year)
|
Chris@16
|
767 {
|
Chris@16
|
768 static const int days_from_0_to_1970 = days_from_0(1970);
|
Chris@16
|
769 return days_from_0(year) - days_from_0_to_1970;
|
Chris@16
|
770 }
|
Chris@16
|
771 inline int32_t days_from_1jan(int32_t year,int32_t month,int32_t day)
|
Chris@16
|
772 {
|
Chris@16
|
773 static const int32_t days[2][12] =
|
Chris@16
|
774 {
|
Chris@16
|
775 { 0,31,59,90,120,151,181,212,243,273,304,334},
|
Chris@16
|
776 { 0,31,60,91,121,152,182,213,244,274,305,335}
|
Chris@16
|
777 };
|
Chris@16
|
778
|
Chris@16
|
779 return days[is_leap(year)][month-1] + day - 1;
|
Chris@16
|
780 }
|
Chris@16
|
781
|
Chris@16
|
782 inline time_t internal_timegm(std::tm const *t)
|
Chris@16
|
783 {
|
Chris@16
|
784 int year = t->tm_year + 1900;
|
Chris@16
|
785 int month = t->tm_mon;
|
Chris@16
|
786 if(month > 11)
|
Chris@16
|
787 {
|
Chris@16
|
788 year += month/12;
|
Chris@16
|
789 month %= 12;
|
Chris@16
|
790 }
|
Chris@16
|
791 else if(month < 0)
|
Chris@16
|
792 {
|
Chris@16
|
793 int years_diff = (-month + 11)/12;
|
Chris@16
|
794 year -= years_diff;
|
Chris@16
|
795 month+=12 * years_diff;
|
Chris@16
|
796 }
|
Chris@16
|
797 month++;
|
Chris@16
|
798 int day = t->tm_mday;
|
Chris@16
|
799 int day_of_year = days_from_1jan(year,month,day);
|
Chris@16
|
800 int days_since_epoch = days_from_1970(year) + day_of_year ;
|
Chris@16
|
801
|
Chris@16
|
802 time_t seconds_in_day = 3600 * 24;
|
Chris@16
|
803 time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;
|
Chris@16
|
804
|
Chris@16
|
805 return result;
|
Chris@16
|
806 }
|
Chris@101
|
807 //#endif
|
Chris@16
|
808
|
Chris@16
|
809 /**
|
Chris@16
|
810 * from_ymd could be made more efficient by using a table
|
Chris@16
|
811 * day_count_table indexed by the y%400.
|
Chris@16
|
812 * This table could contain the day_count
|
Chris@16
|
813 * by*365 + by/4 - by/100 + by/400
|
Chris@16
|
814 *
|
Chris@16
|
815 * from_ymd = (by/400)*days_by_400_years+day_count_table[by%400] +
|
Chris@16
|
816 * days_in_year_before[is_leap_table[by%400]][m-1] + d;
|
Chris@16
|
817 */
|
Chris@16
|
818 inline unsigned days_before_years(int32_t y)
|
Chris@16
|
819 {
|
Chris@16
|
820 return y * 365 + y / 4 - y / 100 + y / 400;
|
Chris@16
|
821 }
|
Chris@16
|
822
|
Chris@16
|
823 // Returns year/month/day triple in civil calendar
|
Chris@16
|
824 // Preconditions: z is number of days since 1970-01-01 and is in the range:
|
Chris@16
|
825 // [numeric_limits<Int>::min(), numeric_limits<Int>::max()-719468].
|
Chris@16
|
826 template <class Int>
|
Chris@16
|
827 //constexpr
|
Chris@16
|
828 void
|
Chris@16
|
829 inline civil_from_days(Int z, Int& y, unsigned& m, unsigned& d) BOOST_NOEXCEPT
|
Chris@16
|
830 {
|
Chris@16
|
831 BOOST_STATIC_ASSERT_MSG(std::numeric_limits<unsigned>::digits >= 18,
|
Chris@16
|
832 "This algorithm has not been ported to a 16 bit unsigned integer");
|
Chris@16
|
833 BOOST_STATIC_ASSERT_MSG(std::numeric_limits<Int>::digits >= 20,
|
Chris@16
|
834 "This algorithm has not been ported to a 16 bit signed integer");
|
Chris@16
|
835 z += 719468;
|
Chris@16
|
836 const Int era = (z >= 0 ? z : z - 146096) / 146097;
|
Chris@16
|
837 const unsigned doe = static_cast<unsigned>(z - era * 146097); // [0, 146096]
|
Chris@16
|
838 const unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399]
|
Chris@16
|
839 y = static_cast<Int>(yoe) + era * 400;
|
Chris@16
|
840 const unsigned doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365]
|
Chris@16
|
841 const unsigned mp = (5*doy + 2)/153; // [0, 11]
|
Chris@16
|
842 d = doy - (153*mp+2)/5 + 1; // [1, 31]
|
Chris@16
|
843 m = mp + (mp < 10 ? 3 : -9); // [1, 12]
|
Chris@16
|
844 y += (m <= 2);
|
Chris@16
|
845 --m;
|
Chris@16
|
846 }
|
Chris@16
|
847 inline std::tm * internal_gmtime(std::time_t const* t, std::tm *tm)
|
Chris@16
|
848 {
|
Chris@16
|
849 if (t==0) return 0;
|
Chris@16
|
850 if (tm==0) return 0;
|
Chris@16
|
851
|
Chris@16
|
852 #if 0
|
Chris@16
|
853 static const unsigned char
|
Chris@16
|
854 day_of_year_month[2][366] =
|
Chris@16
|
855 {
|
Chris@16
|
856 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 },
|
Chris@16
|
857
|
Chris@16
|
858 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
|
Chris@16
|
859
|
Chris@16
|
860 } };
|
Chris@16
|
861
|
Chris@16
|
862 static const int32_t days_in_year_before[2][13] =
|
Chris@16
|
863 {
|
Chris@16
|
864 { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 },
|
Chris@16
|
865 { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }
|
Chris@16
|
866 };
|
Chris@16
|
867 #endif
|
Chris@16
|
868
|
Chris@16
|
869 const time_t seconds_in_day = 3600 * 24;
|
Chris@16
|
870 int32_t days_since_epoch = static_cast<int32_t>(*t / seconds_in_day);
|
Chris@16
|
871 int32_t hms = static_cast<int32_t>(*t - seconds_in_day*days_since_epoch);
|
Chris@16
|
872 if (hms < 0) {
|
Chris@16
|
873 days_since_epoch-=1;
|
Chris@16
|
874 hms = seconds_in_day+hms;
|
Chris@16
|
875 }
|
Chris@16
|
876
|
Chris@16
|
877 #if 0
|
Chris@16
|
878 int32_t x = days_since_epoch;
|
Chris@16
|
879 int32_t y = static_cast<int32_t> (static_cast<long long> (x + 2) * 400
|
Chris@16
|
880 / 146097);
|
Chris@16
|
881 const int32_t ym1 = y - 1;
|
Chris@16
|
882 int32_t doy = x - days_before_years(y);
|
Chris@16
|
883 const int32_t doy1 = x - days_before_years(ym1);
|
Chris@16
|
884 const int32_t N = std::numeric_limits<int>::digits - 1;
|
Chris@16
|
885 const int32_t mask1 = doy >> N; // arithmetic rshift - not portable - but nearly universal
|
Chris@16
|
886 const int32_t mask0 = ~mask1;
|
Chris@16
|
887 doy = (doy & mask0) | (doy1 & mask1);
|
Chris@16
|
888 y = (y & mask0) | (ym1 & mask1);
|
Chris@16
|
889 //y -= 32767 + 2;
|
Chris@16
|
890 y += 70;
|
Chris@16
|
891 tm->tm_year=y;
|
Chris@16
|
892 const int32_t leap = is_leap(y);
|
Chris@16
|
893 tm->tm_mon = day_of_year_month[leap][doy]-1;
|
Chris@16
|
894 tm->tm_mday = doy - days_in_year_before[leap][tm->tm_mon] ;
|
Chris@16
|
895 #else
|
Chris@16
|
896 int32_t y;
|
Chris@16
|
897 unsigned m, d;
|
Chris@16
|
898 civil_from_days(days_since_epoch, y, m, d);
|
Chris@16
|
899 tm->tm_year=y-1900; tm->tm_mon=m; tm->tm_mday=d;
|
Chris@16
|
900 #endif
|
Chris@16
|
901
|
Chris@16
|
902 tm->tm_hour = hms / 3600;
|
Chris@16
|
903 const int ms = hms % 3600;
|
Chris@16
|
904 tm->tm_min = ms / 60;
|
Chris@16
|
905 tm->tm_sec = ms % 60;
|
Chris@16
|
906
|
Chris@16
|
907 tm->tm_isdst = -1;
|
Chris@16
|
908 (void)mktime(tm);
|
Chris@16
|
909 return tm;
|
Chris@16
|
910 }
|
Chris@16
|
911
|
Chris@16
|
912 } // detail
|
Chris@16
|
913 #ifndef BOOST_CHRONO_NO_UTC_TIMEPOINT
|
Chris@16
|
914
|
Chris@16
|
915 #if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
|
Chris@16
|
916
|
Chris@16
|
917 template <class CharT, class Traits, class Duration>
|
Chris@16
|
918 std::basic_ostream<CharT, Traits>&
|
Chris@16
|
919 operator<<(std::basic_ostream<CharT, Traits>& os, const time_point<system_clock, Duration>& tp)
|
Chris@16
|
920 {
|
Chris@16
|
921 typename std::basic_ostream<CharT, Traits>::sentry ok(os);
|
Chris@16
|
922 if (bool(ok))
|
Chris@16
|
923 {
|
Chris@16
|
924 bool failed = false;
|
Chris@16
|
925 BOOST_TRY
|
Chris@16
|
926 {
|
Chris@16
|
927 const CharT* pb = 0; //nullptr;
|
Chris@16
|
928 const CharT* pe = pb;
|
Chris@16
|
929 std::basic_string<CharT> fmt = get_time_fmt<CharT> (os);
|
Chris@16
|
930 pb = fmt.data();
|
Chris@16
|
931 pe = pb + fmt.size();
|
Chris@16
|
932
|
Chris@16
|
933 timezone tz = get_timezone(os);
|
Chris@16
|
934 std::locale loc = os.getloc();
|
Chris@16
|
935 time_t t = system_clock::to_time_t(time_point_cast<system_clock::duration>(tp));
|
Chris@16
|
936 std::tm tm;
|
Chris@16
|
937 std::memset(&tm, 0, sizeof(std::tm));
|
Chris@16
|
938 if (tz == timezone::local)
|
Chris@16
|
939 {
|
Chris@16
|
940 #if defined BOOST_WINDOWS && ! defined(__CYGWIN__)
|
Chris@16
|
941 std::tm *tmp = 0;
|
Chris@16
|
942 if ((tmp=localtime(&t)) == 0)
|
Chris@16
|
943 failed = true;
|
Chris@16
|
944 else
|
Chris@16
|
945 tm =*tmp;
|
Chris@16
|
946 #else
|
Chris@16
|
947 if (localtime_r(&t, &tm) == 0) failed = true;
|
Chris@16
|
948 #endif
|
Chris@16
|
949 }
|
Chris@16
|
950 else
|
Chris@16
|
951 {
|
Chris@16
|
952 #if BOOST_CHRONO_INTERNAL_GMTIME
|
Chris@16
|
953 if (detail::internal_gmtime(&t, &tm) == 0) failed = true;
|
Chris@16
|
954
|
Chris@16
|
955 #elif defined BOOST_WINDOWS && ! defined(__CYGWIN__)
|
Chris@16
|
956 std::tm *tmp = 0;
|
Chris@16
|
957 if((tmp = gmtime(&t)) == 0)
|
Chris@16
|
958 failed = true;
|
Chris@16
|
959 else
|
Chris@16
|
960 tm = *tmp;
|
Chris@16
|
961 #else
|
Chris@16
|
962 if (gmtime_r(&t, &tm) == 0) failed = true;
|
Chris@16
|
963 tm.tm_isdst = -1;
|
Chris@16
|
964 (void)mktime(&tm);
|
Chris@16
|
965
|
Chris@16
|
966 #endif
|
Chris@16
|
967
|
Chris@16
|
968 }
|
Chris@16
|
969 if (!failed)
|
Chris@16
|
970 {
|
Chris@16
|
971 const std::time_put<CharT>& tpf = std::use_facet<std::time_put<CharT> >(loc);
|
Chris@16
|
972 if (pb == pe)
|
Chris@16
|
973 {
|
Chris@16
|
974 CharT pattern[] =
|
Chris@16
|
975 { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' };
|
Chris@16
|
976 pb = pattern;
|
Chris@16
|
977 pe = pb + sizeof (pattern) / sizeof(CharT);
|
Chris@16
|
978 failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
|
Chris@16
|
979 if (!failed)
|
Chris@16
|
980 {
|
Chris@16
|
981 duration<fractional_seconds> d = tp - system_clock::from_time_t(t) + seconds(tm.tm_sec);
|
Chris@16
|
982 if (d.count() < 10) os << CharT('0');
|
Chris@16
|
983 //if (! os.good()) {
|
Chris@16
|
984 // throw "exception";
|
Chris@16
|
985 //}
|
Chris@16
|
986 std::ios::fmtflags flgs = os.flags();
|
Chris@16
|
987 os.setf(std::ios::fixed, std::ios::floatfield);
|
Chris@16
|
988 //if (! os.good()) {
|
Chris@16
|
989 //throw "exception";
|
Chris@16
|
990 //}
|
Chris@16
|
991 os.precision(9);
|
Chris@16
|
992 os << d.count();
|
Chris@16
|
993 //if (! os.good()) {
|
Chris@16
|
994 //throw "exception";
|
Chris@16
|
995 //}
|
Chris@16
|
996 os.flags(flgs);
|
Chris@16
|
997 if (tz == timezone::local)
|
Chris@16
|
998 {
|
Chris@16
|
999 CharT sub_pattern[] =
|
Chris@16
|
1000 { ' ', '%', 'z' };
|
Chris@16
|
1001 pb = sub_pattern;
|
Chris@16
|
1002 pe = pb + +sizeof (sub_pattern) / sizeof(CharT);
|
Chris@16
|
1003 failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
|
Chris@16
|
1004 }
|
Chris@16
|
1005 else
|
Chris@16
|
1006 {
|
Chris@16
|
1007 CharT sub_pattern[] =
|
Chris@16
|
1008 { ' ', '+', '0', '0', '0', '0', 0 };
|
Chris@16
|
1009 os << sub_pattern;
|
Chris@16
|
1010 }
|
Chris@16
|
1011 }
|
Chris@16
|
1012 }
|
Chris@16
|
1013 else
|
Chris@16
|
1014 {
|
Chris@16
|
1015 failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
|
Chris@16
|
1016 }
|
Chris@16
|
1017 }
|
Chris@16
|
1018 }
|
Chris@16
|
1019 BOOST_CATCH (...)
|
Chris@16
|
1020 {
|
Chris@16
|
1021 failed = true;
|
Chris@16
|
1022 }
|
Chris@16
|
1023 BOOST_CATCH_END
|
Chris@16
|
1024 if (failed)
|
Chris@16
|
1025 {
|
Chris@16
|
1026 os.setstate(std::ios_base::failbit | std::ios_base::badbit);
|
Chris@16
|
1027 }
|
Chris@16
|
1028 }
|
Chris@16
|
1029 return os;
|
Chris@16
|
1030 }
|
Chris@16
|
1031 #endif
|
Chris@16
|
1032
|
Chris@16
|
1033 namespace detail
|
Chris@16
|
1034 {
|
Chris@16
|
1035
|
Chris@16
|
1036 template <class CharT, class InputIterator>
|
Chris@16
|
1037 minutes extract_z(InputIterator& b, InputIterator e, std::ios_base::iostate& err, const std::ctype<CharT>& ct)
|
Chris@16
|
1038 {
|
Chris@16
|
1039 int min = 0;
|
Chris@16
|
1040 if (b != e)
|
Chris@16
|
1041 {
|
Chris@16
|
1042 char cn = ct.narrow(*b, 0);
|
Chris@16
|
1043 if (cn != '+' && cn != '-')
|
Chris@16
|
1044 {
|
Chris@16
|
1045 err |= std::ios_base::failbit;
|
Chris@16
|
1046 return minutes(0);
|
Chris@16
|
1047 }
|
Chris@16
|
1048 int sn = cn == '-' ? -1 : 1;
|
Chris@16
|
1049 int hr = 0;
|
Chris@16
|
1050 for (int i = 0; i < 2; ++i)
|
Chris@16
|
1051 {
|
Chris@16
|
1052 if (++b == e)
|
Chris@16
|
1053 {
|
Chris@16
|
1054 err |= std::ios_base::eofbit | std::ios_base::failbit;
|
Chris@16
|
1055 return minutes(0);
|
Chris@16
|
1056 }
|
Chris@16
|
1057 cn = ct.narrow(*b, 0);
|
Chris@16
|
1058 if (! ('0' <= cn && cn <= '9'))
|
Chris@16
|
1059 {
|
Chris@16
|
1060 err |= std::ios_base::failbit;
|
Chris@16
|
1061 return minutes(0);
|
Chris@16
|
1062 }
|
Chris@16
|
1063 hr = hr * 10 + cn - '0';
|
Chris@16
|
1064 }
|
Chris@16
|
1065 for (int i = 0; i < 2; ++i)
|
Chris@16
|
1066 {
|
Chris@16
|
1067 if (++b == e)
|
Chris@16
|
1068 {
|
Chris@16
|
1069 err |= std::ios_base::eofbit | std::ios_base::failbit;
|
Chris@16
|
1070 return minutes(0);
|
Chris@16
|
1071 }
|
Chris@16
|
1072 cn = ct.narrow(*b, 0);
|
Chris@16
|
1073 if (! ('0' <= cn && cn <= '9'))
|
Chris@16
|
1074 {
|
Chris@16
|
1075 err |= std::ios_base::failbit;
|
Chris@16
|
1076 return minutes(0);
|
Chris@16
|
1077 }
|
Chris@16
|
1078 min = min * 10 + cn - '0';
|
Chris@16
|
1079 }
|
Chris@16
|
1080 if (++b == e) {
|
Chris@16
|
1081 err |= std::ios_base::eofbit;
|
Chris@16
|
1082 }
|
Chris@16
|
1083 min += hr * 60;
|
Chris@16
|
1084 min *= sn;
|
Chris@16
|
1085 }
|
Chris@16
|
1086 else
|
Chris@16
|
1087 {
|
Chris@16
|
1088 err |= std::ios_base::eofbit | std::ios_base::failbit;
|
Chris@16
|
1089 }
|
Chris@16
|
1090 return minutes(min);
|
Chris@16
|
1091 }
|
Chris@16
|
1092
|
Chris@16
|
1093 } // detail
|
Chris@16
|
1094
|
Chris@16
|
1095 #if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
|
Chris@16
|
1096
|
Chris@16
|
1097 template <class CharT, class Traits, class Duration>
|
Chris@16
|
1098 std::basic_istream<CharT, Traits>&
|
Chris@16
|
1099 operator>>(std::basic_istream<CharT, Traits>& is, time_point<system_clock, Duration>& tp)
|
Chris@16
|
1100 {
|
Chris@16
|
1101 typename std::basic_istream<CharT, Traits>::sentry ok(is);
|
Chris@16
|
1102 if (bool(ok))
|
Chris@16
|
1103 {
|
Chris@16
|
1104 std::ios_base::iostate err = std::ios_base::goodbit;
|
Chris@16
|
1105 BOOST_TRY
|
Chris@16
|
1106 {
|
Chris@16
|
1107 const CharT* pb = 0; //nullptr;
|
Chris@16
|
1108 const CharT* pe = pb;
|
Chris@16
|
1109 std::basic_string<CharT> fmt = get_time_fmt<CharT> (is);
|
Chris@16
|
1110 pb = fmt.data();
|
Chris@16
|
1111 pe = pb + fmt.size();
|
Chris@16
|
1112
|
Chris@16
|
1113 timezone tz = get_timezone(is);
|
Chris@16
|
1114 std::locale loc = is.getloc();
|
Chris@16
|
1115 const std::time_get<CharT>& tg = std::use_facet<std::time_get<CharT> >(loc);
|
Chris@16
|
1116 const std::ctype<CharT>& ct = std::use_facet<std::ctype<CharT> >(loc);
|
Chris@16
|
1117 tm tm; // {0}
|
Chris@16
|
1118 std::memset(&tm, 0, sizeof(std::tm));
|
Chris@16
|
1119
|
Chris@16
|
1120 typedef std::istreambuf_iterator<CharT, Traits> It;
|
Chris@16
|
1121 if (pb == pe)
|
Chris@16
|
1122 {
|
Chris@16
|
1123 CharT pattern[] =
|
Chris@16
|
1124 { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' };
|
Chris@16
|
1125 pb = pattern;
|
Chris@16
|
1126 pe = pb + sizeof (pattern) / sizeof(CharT);
|
Chris@16
|
1127
|
Chris@16
|
1128 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
|
Chris@16
|
1129 const detail::time_get<CharT>& dtg(tg);
|
Chris@16
|
1130 dtg.get(is, 0, is, err, &tm, pb, pe);
|
Chris@16
|
1131 #else
|
Chris@16
|
1132 tg.get(is, 0, is, err, &tm, pb, pe);
|
Chris@16
|
1133 #endif
|
Chris@16
|
1134 if (err & std::ios_base::failbit) goto exit;
|
Chris@16
|
1135 fractional_seconds sec;
|
Chris@16
|
1136 CharT c = CharT();
|
Chris@16
|
1137 std::ios::fmtflags flgs = is.flags();
|
Chris@16
|
1138 is.setf(std::ios::fixed, std::ios::floatfield);
|
Chris@16
|
1139 is.precision(9);
|
Chris@16
|
1140 is >> sec;
|
Chris@16
|
1141 is.flags(flgs);
|
Chris@16
|
1142 if (is.fail())
|
Chris@16
|
1143 {
|
Chris@16
|
1144 err |= std::ios_base::failbit;
|
Chris@16
|
1145 goto exit;
|
Chris@16
|
1146 }
|
Chris@16
|
1147 It i(is);
|
Chris@16
|
1148 It eof;
|
Chris@16
|
1149 c = *i;
|
Chris@16
|
1150 if (++i == eof || c != ' ')
|
Chris@16
|
1151 {
|
Chris@16
|
1152 err |= std::ios_base::failbit;
|
Chris@16
|
1153 goto exit;
|
Chris@16
|
1154 }
|
Chris@16
|
1155 minutes min = detail::extract_z(i, eof, err, ct);
|
Chris@16
|
1156
|
Chris@16
|
1157 if (err & std::ios_base::failbit) goto exit;
|
Chris@16
|
1158 time_t t;
|
Chris@16
|
1159
|
Chris@16
|
1160 #if BOOST_CHRONO_INTERNAL_TIMEGM
|
Chris@16
|
1161 t = detail::internal_timegm(&tm);
|
Chris@16
|
1162 #else
|
Chris@16
|
1163 t = timegm(&tm);
|
Chris@16
|
1164 #endif
|
Chris@16
|
1165 tp = time_point_cast<Duration>(
|
Chris@16
|
1166 system_clock::from_time_t(t) - min + round<system_clock::duration> (duration<fractional_seconds> (sec))
|
Chris@16
|
1167 );
|
Chris@16
|
1168 }
|
Chris@16
|
1169 else
|
Chris@16
|
1170 {
|
Chris@16
|
1171 const CharT z[2] =
|
Chris@16
|
1172 { '%', 'z' };
|
Chris@16
|
1173 const CharT* fz = std::search(pb, pe, z, z + 2);
|
Chris@16
|
1174 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
|
Chris@16
|
1175 const detail::time_get<CharT>& dtg(tg);
|
Chris@16
|
1176 dtg.get(is, 0, is, err, &tm, pb, fz);
|
Chris@16
|
1177 #else
|
Chris@16
|
1178 tg.get(is, 0, is, err, &tm, pb, fz);
|
Chris@16
|
1179 #endif
|
Chris@16
|
1180 minutes minu(0);
|
Chris@16
|
1181 if (fz != pe)
|
Chris@16
|
1182 {
|
Chris@16
|
1183 if (err != std::ios_base::goodbit)
|
Chris@16
|
1184 {
|
Chris@16
|
1185 err |= std::ios_base::failbit;
|
Chris@16
|
1186 goto exit;
|
Chris@16
|
1187 }
|
Chris@16
|
1188 It i(is);
|
Chris@16
|
1189 It eof;
|
Chris@16
|
1190 minu = detail::extract_z(i, eof, err, ct);
|
Chris@16
|
1191 if (err & std::ios_base::failbit) goto exit;
|
Chris@16
|
1192 if (fz + 2 != pe)
|
Chris@16
|
1193 {
|
Chris@16
|
1194 if (err != std::ios_base::goodbit)
|
Chris@16
|
1195 {
|
Chris@16
|
1196 err |= std::ios_base::failbit;
|
Chris@16
|
1197 goto exit;
|
Chris@16
|
1198 }
|
Chris@16
|
1199 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
|
Chris@16
|
1200 const detail::time_get<CharT>& dtg(tg);
|
Chris@16
|
1201 dtg.get(is, 0, is, err, &tm, fz + 2, pe);
|
Chris@16
|
1202 #else
|
Chris@16
|
1203 tg.get(is, 0, is, err, &tm, fz + 2, pe);
|
Chris@16
|
1204 #endif
|
Chris@16
|
1205 if (err & std::ios_base::failbit) goto exit;
|
Chris@16
|
1206 }
|
Chris@16
|
1207 }
|
Chris@16
|
1208 tm.tm_isdst = -1;
|
Chris@16
|
1209 time_t t;
|
Chris@16
|
1210 if (tz == timezone::utc || fz != pe)
|
Chris@16
|
1211 {
|
Chris@16
|
1212 #if BOOST_CHRONO_INTERNAL_TIMEGM
|
Chris@16
|
1213 t = detail::internal_timegm(&tm);
|
Chris@16
|
1214 #else
|
Chris@16
|
1215 t = timegm(&tm);
|
Chris@16
|
1216 #endif
|
Chris@16
|
1217 }
|
Chris@16
|
1218 else
|
Chris@16
|
1219 {
|
Chris@16
|
1220 t = mktime(&tm);
|
Chris@16
|
1221 }
|
Chris@16
|
1222 tp = time_point_cast<Duration>(
|
Chris@16
|
1223 system_clock::from_time_t(t) - minu
|
Chris@16
|
1224 );
|
Chris@16
|
1225 }
|
Chris@16
|
1226 }
|
Chris@16
|
1227 BOOST_CATCH (...)
|
Chris@16
|
1228 {
|
Chris@16
|
1229 err |= std::ios_base::badbit | std::ios_base::failbit;
|
Chris@16
|
1230 }
|
Chris@16
|
1231 BOOST_CATCH_END
|
Chris@16
|
1232 exit: is.setstate(err);
|
Chris@16
|
1233 }
|
Chris@16
|
1234 return is;
|
Chris@16
|
1235 }
|
Chris@16
|
1236
|
Chris@16
|
1237 #endif
|
Chris@16
|
1238 #endif //UTC
|
Chris@16
|
1239 } // chrono
|
Chris@16
|
1240
|
Chris@16
|
1241 }
|
Chris@16
|
1242
|
Chris@16
|
1243 #endif // header
|