time_point_io.hpp 41 KB

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