time_point_io.hpp 40 KB

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