File indexing completed on 2025-01-18 09:29:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_CHRONO_IO_TIME_POINT_IO_HPP
0020 #define BOOST_CHRONO_IO_TIME_POINT_IO_HPP
0021
0022 #include <boost/chrono/io/time_point_put.hpp>
0023 #include <boost/chrono/io/time_point_get.hpp>
0024 #include <boost/chrono/io/duration_io.hpp>
0025 #include <boost/chrono/io/ios_base_state.hpp>
0026 #include <boost/chrono/io/utility/manip_base.hpp>
0027 #include <boost/chrono/time_point.hpp>
0028 #include <boost/chrono/clock_string.hpp>
0029 #include <boost/chrono/round.hpp>
0030 #include <boost/chrono/detail/scan_keyword.hpp>
0031 #include <boost/static_assert.hpp>
0032 #include <boost/core/no_exceptions_support.hpp>
0033 #include <cstring>
0034 #include <locale>
0035 #include <ctime>
0036
0037 #if ( defined BOOST_WINDOWS && ! defined(__CYGWIN__) ) \
0038 || (defined(sun) || defined(__sun)) \
0039 || (defined __IBMCPP__) \
0040 || defined __ANDROID__ \
0041 || defined __QNXNTO__ \
0042 || (defined(_AIX) && defined __GNUC__)
0043 #define BOOST_CHRONO_INTERNAL_TIMEGM
0044 #endif
0045
0046 #if (defined BOOST_WINDOWS && ! defined(__CYGWIN__)) \
0047 || ( (defined(sun) || defined(__sun)) && defined __GNUC__) \
0048 || (defined __IBMCPP__) \
0049 || defined __ANDROID__ \
0050 || (defined(_AIX) && defined __GNUC__)
0051 #define BOOST_CHRONO_INTERNAL_GMTIME
0052 #endif
0053
0054 #define BOOST_CHRONO_USES_INTERNAL_TIME_GET
0055
0056 namespace boost
0057 {
0058 namespace chrono
0059 {
0060 typedef double fractional_seconds;
0061 namespace detail
0062 {
0063
0064
0065 template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
0066 struct time_get
0067 {
0068 std::time_get<CharT> const &that_;
0069 time_get(std::time_get<CharT> const& that) : that_(that) {}
0070
0071 typedef std::time_get<CharT> facet;
0072 typedef typename facet::iter_type iter_type;
0073 typedef typename facet::char_type char_type;
0074 typedef std::basic_string<char_type> string_type;
0075
0076 static int
0077 get_up_to_n_digits(
0078 InputIterator& b, InputIterator e,
0079 std::ios_base::iostate& err,
0080 const std::ctype<CharT>& ct,
0081 int n)
0082 {
0083
0084 if (b == e)
0085 {
0086 err |= std::ios_base::eofbit | std::ios_base::failbit;
0087 return 0;
0088 }
0089
0090 CharT c = *b;
0091 if (!ct.is(std::ctype_base::digit, c))
0092 {
0093 err |= std::ios_base::failbit;
0094 return 0;
0095 }
0096 int r = ct.narrow(c, 0) - '0';
0097 for (++b, --n; b != e && n > 0; ++b, --n)
0098 {
0099
0100 c = *b;
0101 if (!ct.is(std::ctype_base::digit, c))
0102 return r;
0103 r = r * 10 + ct.narrow(c, 0) - '0';
0104 }
0105 if (b == e)
0106 err |= std::ios_base::eofbit;
0107 return r;
0108 }
0109
0110
0111 void get_day(
0112 int& d,
0113 iter_type& b, iter_type e,
0114 std::ios_base::iostate& err,
0115 const std::ctype<char_type>& ct) const
0116 {
0117 int t = get_up_to_n_digits(b, e, err, ct, 2);
0118 if (!(err & std::ios_base::failbit) && 1 <= t && t <= 31)
0119 d = t;
0120 else
0121 err |= std::ios_base::failbit;
0122 }
0123
0124 void get_month(
0125 int& m,
0126 iter_type& b, iter_type e,
0127 std::ios_base::iostate& err,
0128 const std::ctype<char_type>& ct) const
0129 {
0130 int t = get_up_to_n_digits(b, e, err, ct, 2);
0131 if (!(err & std::ios_base::failbit) && 1 <= t && t <= 12)
0132 m = --t;
0133 else
0134 err |= std::ios_base::failbit;
0135 }
0136
0137
0138 void get_year4(int& y,
0139 iter_type& b, iter_type e,
0140 std::ios_base::iostate& err,
0141 const std::ctype<char_type>& ct) const
0142 {
0143 int t = get_up_to_n_digits(b, e, err, ct, 4);
0144 if (!(err & std::ios_base::failbit))
0145 y = t - 1900;
0146 }
0147
0148 void
0149 get_hour(int& h,
0150 iter_type& b, iter_type e,
0151 std::ios_base::iostate& err,
0152 const std::ctype<char_type>& ct) const
0153 {
0154 int t = get_up_to_n_digits(b, e, err, ct, 2);
0155 if (!(err & std::ios_base::failbit) && t <= 23)
0156 h = t;
0157 else
0158 err |= std::ios_base::failbit;
0159 }
0160
0161 void
0162 get_minute(int& m,
0163 iter_type& b, iter_type e,
0164 std::ios_base::iostate& err,
0165 const std::ctype<char_type>& ct) const
0166 {
0167 int t = get_up_to_n_digits(b, e, err, ct, 2);
0168 if (!(err & std::ios_base::failbit) && t <= 59)
0169 m = t;
0170 else
0171 err |= std::ios_base::failbit;
0172 }
0173
0174 void get_second(int& s,
0175 iter_type& b, iter_type e,
0176 std::ios_base::iostate& err,
0177 const std::ctype<char_type>& ct) const
0178 {
0179 int t = get_up_to_n_digits(b, e, err, ct, 2);
0180 if (!(err & std::ios_base::failbit) && t <= 60)
0181 s = t;
0182 else
0183 err |= std::ios_base::failbit;
0184 }
0185
0186 void get_white_space(iter_type& b, iter_type e,
0187 std::ios_base::iostate& err,
0188 const std::ctype<char_type>& ct) const
0189 {
0190 for (; b != e && ct.is(std::ctype_base::space, *b); ++b)
0191 ;
0192 if (b == e)
0193 err |= std::ios_base::eofbit;
0194 }
0195
0196 void get_12_hour(int& h,
0197 iter_type& b, iter_type e,
0198 std::ios_base::iostate& err,
0199 const std::ctype<char_type>& ct) const
0200 {
0201 int t = get_up_to_n_digits(b, e, err, ct, 2);
0202 if (!(err & std::ios_base::failbit) && 1 <= t && t <= 12)
0203 h = t;
0204 else
0205 err |= std::ios_base::failbit;
0206 }
0207
0208 void get_percent(iter_type& b, iter_type e,
0209 std::ios_base::iostate& err,
0210 const std::ctype<char_type>& ct) const
0211 {
0212 if (b == e)
0213 {
0214 err |= std::ios_base::eofbit | std::ios_base::failbit;
0215 return;
0216 }
0217 if (ct.narrow(*b, 0) != '%')
0218 err |= std::ios_base::failbit;
0219 else if(++b == e)
0220 err |= std::ios_base::eofbit;
0221 }
0222
0223 void get_day_year_num(int& d,
0224 iter_type& b, iter_type e,
0225 std::ios_base::iostate& err,
0226 const std::ctype<char_type>& ct) const
0227 {
0228 int t = get_up_to_n_digits(b, e, err, ct, 3);
0229 if (!(err & std::ios_base::failbit) && 1 <= t && t <= 366)
0230 d = --t;
0231 else
0232 err |= std::ios_base::failbit;
0233 }
0234
0235 void
0236 get_weekday(int& w,
0237 iter_type& b, iter_type e,
0238 std::ios_base::iostate& err,
0239 const std::ctype<char_type>& ct) const
0240 {
0241 int t = get_up_to_n_digits(b, e, err, ct, 1);
0242 if (!(err & std::ios_base::failbit) && t <= 6)
0243 w = t;
0244 else
0245 err |= std::ios_base::failbit;
0246 }
0247 #if 0
0248
0249 void
0250 get_am_pm(int& h,
0251 iter_type& b, iter_type e,
0252 std::ios_base::iostate& err,
0253 const std::ctype<char_type>& ct) const
0254 {
0255 const string_type* ap = am_pm();
0256 if (ap[0].size() + ap[1].size() == 0)
0257 {
0258 err |= ios_base::failbit;
0259 return;
0260 }
0261 ptrdiff_t i = detail::scan_keyword(b, e, ap, ap+2, ct, err, false) - ap;
0262 if (i == 0 && h == 12)
0263 h = 0;
0264 else if (i == 1 && h < 12)
0265 h += 12;
0266 }
0267
0268 #endif
0269
0270 InputIterator get(
0271 iter_type b, iter_type e,
0272 std::ios_base& iob,
0273 std::ios_base::iostate& err,
0274 std::tm* tm,
0275 char fmt, char) const
0276 {
0277 err = std::ios_base::goodbit;
0278 const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(iob.getloc());
0279
0280 switch (fmt)
0281 {
0282 case 'a':
0283 case 'A':
0284 {
0285 std::tm tm2;
0286 std::memset(&tm2, 0, sizeof(std::tm));
0287 that_.get_weekday(b, e, iob, err, &tm2);
0288
0289 }
0290 break;
0291 case 'b':
0292 case 'B':
0293 case 'h':
0294 {
0295 std::tm tm2;
0296 std::memset(&tm2, 0, sizeof(std::tm));
0297 that_.get_monthname(b, e, iob, err, &tm2);
0298
0299 }
0300 break;
0301
0302
0303
0304
0305
0306
0307 case 'd':
0308 case 'e':
0309 get_day(tm->tm_mday, b, e, err, ct);
0310 break;
0311 case 'D':
0312 {
0313 const char_type fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
0314 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
0315 }
0316 break;
0317 case 'F':
0318 {
0319 const char_type fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
0320 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
0321 }
0322 break;
0323 case 'H':
0324 get_hour(tm->tm_hour, b, e, err, ct);
0325 break;
0326 case 'I':
0327 get_12_hour(tm->tm_hour, b, e, err, ct);
0328 break;
0329 case 'j':
0330 get_day_year_num(tm->tm_yday, b, e, err, ct);
0331 break;
0332 case 'm':
0333 get_month(tm->tm_mon, b, e, err, ct);
0334 break;
0335 case 'M':
0336 get_minute(tm->tm_min, b, e, err, ct);
0337 break;
0338 case 'n':
0339 case 't':
0340 get_white_space(b, e, err, ct);
0341 break;
0342
0343
0344
0345 case 'r':
0346 {
0347 const char_type fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
0348 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
0349 }
0350 break;
0351 case 'R':
0352 {
0353 const char_type fm[] = {'%', 'H', ':', '%', 'M'};
0354 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
0355 }
0356 break;
0357 case 'S':
0358 get_second(tm->tm_sec, b, e, err, ct);
0359 break;
0360 case 'T':
0361 {
0362 const char_type fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
0363 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
0364 }
0365 break;
0366 case 'w':
0367 {
0368 get_weekday(tm->tm_wday, b, e, err, ct);
0369 }
0370 break;
0371 case 'x':
0372 return that_.get_date(b, e, iob, err, tm);
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382 break;
0383 case 'Y':
0384 get_year4(tm->tm_year, b, e, err, ct);
0385 break;
0386 case '%':
0387 get_percent(b, e, err, ct);
0388 break;
0389 default:
0390 err |= std::ios_base::failbit;
0391 }
0392 return b;
0393 }
0394
0395
0396 InputIterator get(
0397 iter_type b, iter_type e,
0398 std::ios_base& iob,
0399 std::ios_base::iostate& err, std::tm* tm,
0400 const char_type* fmtb, const char_type* fmte) const
0401 {
0402 const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(iob.getloc());
0403 err = std::ios_base::goodbit;
0404 while (fmtb != fmte && err == std::ios_base::goodbit)
0405 {
0406 if (b == e)
0407 {
0408 err = std::ios_base::failbit;
0409 break;
0410 }
0411 if (ct.narrow(*fmtb, 0) == '%')
0412 {
0413 if (++fmtb == fmte)
0414 {
0415 err = std::ios_base::failbit;
0416 break;
0417 }
0418 char cmd = ct.narrow(*fmtb, 0);
0419 char opt = '\0';
0420 if (cmd == 'E' || cmd == '0')
0421 {
0422 if (++fmtb == fmte)
0423 {
0424 err = std::ios_base::failbit;
0425 break;
0426 }
0427 opt = cmd;
0428 cmd = ct.narrow(*fmtb, 0);
0429 }
0430 b = get(b, e, iob, err, tm, cmd, opt);
0431 ++fmtb;
0432 }
0433 else if (ct.is(std::ctype_base::space, *fmtb))
0434 {
0435 for (++fmtb; fmtb != fmte && ct.is(std::ctype_base::space, *fmtb); ++fmtb)
0436 ;
0437 for ( ; b != e && ct.is(std::ctype_base::space, *b); ++b)
0438 ;
0439 }
0440 else if (ct.toupper(*b) == ct.toupper(*fmtb))
0441 {
0442 ++b;
0443 ++fmtb;
0444 }
0445 else
0446 err = std::ios_base::failbit;
0447 }
0448 if (b == e)
0449 err |= std::ios_base::eofbit;
0450 return b;
0451 }
0452
0453 };
0454
0455
0456 template <class CharT>
0457 class time_manip: public manip<time_manip<CharT> >
0458 {
0459 std::basic_string<CharT> fmt_;
0460 timezone tz_;
0461 public:
0462
0463 time_manip(timezone tz, std::basic_string<CharT> fmt)
0464
0465 :
0466 fmt_(fmt), tz_(tz)
0467 {
0468 }
0469
0470
0471
0472
0473 void operator()(std::ios_base &ios) const
0474 {
0475 set_time_fmt<CharT> (ios, fmt_);
0476 set_timezone(ios, tz_);
0477 }
0478 };
0479
0480 class time_man: public manip<time_man>
0481 {
0482 timezone tz_;
0483 public:
0484
0485 time_man(timezone tz)
0486
0487 :
0488 tz_(tz)
0489 {
0490 }
0491
0492
0493
0494
0495 void operator()(std::ios_base &ios) const
0496 {
0497
0498 set_timezone(ios, tz_);
0499 }
0500 };
0501
0502 }
0503
0504 template <class CharT>
0505 inline detail::time_manip<CharT> time_fmt(timezone tz, const CharT* fmt)
0506 {
0507 return detail::time_manip<CharT>(tz, fmt);
0508 }
0509
0510 template <class CharT>
0511 inline detail::time_manip<CharT> time_fmt(timezone tz, std::basic_string<CharT> fmt)
0512 {
0513
0514 return detail::time_manip<CharT>(tz, fmt);
0515 }
0516
0517 inline detail::time_man time_fmt(timezone f)
0518 {
0519 return detail::time_man(f);
0520 }
0521
0522
0523
0524
0525
0526
0527 template <typename CharT = char, typename Traits = std::char_traits<CharT> >
0528 struct time_fmt_io_saver
0529 {
0530
0531
0532
0533 typedef std::ios_base state_type;
0534
0535
0536 typedef std::basic_string<CharT, Traits> aspect_type;
0537
0538
0539
0540
0541
0542
0543 explicit time_fmt_io_saver(state_type &s) :
0544 s_save_(s), a_save_(get_time_fmt<CharT>(s_save_))
0545 {
0546 }
0547
0548
0549
0550
0551
0552
0553 time_fmt_io_saver(state_type &s, aspect_type new_value) :
0554 s_save_(s), a_save_(get_time_fmt<CharT>(s_save_))
0555 {
0556 set_time_fmt(s_save_, new_value);
0557 }
0558
0559
0560
0561
0562
0563
0564 ~time_fmt_io_saver()
0565 {
0566 this->restore();
0567 }
0568
0569
0570
0571
0572 void restore()
0573 {
0574 set_time_fmt(s_save_, a_save_);
0575 }
0576 private:
0577 state_type& s_save_;
0578 aspect_type a_save_;
0579 };
0580
0581
0582
0583
0584
0585
0586 struct timezone_io_saver
0587 {
0588
0589
0590 typedef std::ios_base state_type;
0591
0592 typedef timezone aspect_type;
0593
0594
0595
0596
0597
0598
0599 explicit timezone_io_saver(state_type &s) :
0600 s_save_(s), a_save_(get_timezone(s_save_))
0601 {
0602 }
0603
0604
0605
0606
0607
0608
0609 timezone_io_saver(state_type &s, aspect_type new_value) :
0610 s_save_(s), a_save_(get_timezone(s_save_))
0611 {
0612 set_timezone(s_save_, new_value);
0613 }
0614
0615
0616
0617
0618
0619
0620 ~timezone_io_saver()
0621 {
0622 this->restore();
0623 }
0624
0625
0626
0627
0628 void restore()
0629 {
0630 set_timezone(s_save_, a_save_);
0631 }
0632 private:
0633 timezone_io_saver& operator=(timezone_io_saver const& rhs) ;
0634
0635 state_type& s_save_;
0636 aspect_type a_save_;
0637 };
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648 template <class CharT, class Traits, class Clock, class Duration>
0649 std::basic_ostream<CharT, Traits>&
0650 operator<<(std::basic_ostream<CharT, Traits>& os, const time_point<Clock, Duration>& tp)
0651 {
0652
0653 bool failed = false;
0654 BOOST_TRY
0655 {
0656 std::ios_base::iostate err = std::ios_base::goodbit;
0657 BOOST_TRY
0658 {
0659 typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
0660 if (bool(opfx))
0661 {
0662 if (!std::has_facet<time_point_put<CharT> >(os.getloc()))
0663 {
0664 if (time_point_put<CharT> ().put(os, os, os.fill(), tp) .failed())
0665 {
0666 err = std::ios_base::badbit;
0667 }
0668 }
0669 else
0670 {
0671 if (std::use_facet<time_point_put<CharT> >(os.getloc()) .put(os, os, os.fill(), tp).failed())
0672 {
0673 err = std::ios_base::badbit;
0674 }
0675 }
0676 os.width(0);
0677 }
0678 }
0679 BOOST_CATCH (...)
0680 {
0681 bool flag = false;
0682 BOOST_TRY
0683 {
0684 os.setstate(std::ios_base::failbit);
0685 }
0686 BOOST_CATCH (const std::ios_base::failure& )
0687 {
0688 flag = true;
0689 }
0690 BOOST_CATCH_END
0691 if (flag) throw;
0692 }
0693 BOOST_CATCH_END
0694 if (err) os.setstate(err);
0695 return os;
0696 }
0697 BOOST_CATCH (...)
0698 {
0699 failed = true;
0700 }
0701 BOOST_CATCH_END
0702 if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
0703 return os;
0704 }
0705
0706 template <class CharT, class Traits, class Clock, class Duration>
0707 std::basic_istream<CharT, Traits>&
0708 operator>>(std::basic_istream<CharT, Traits>& is, time_point<Clock, Duration>& tp)
0709 {
0710 std::ios_base::iostate err = std::ios_base::goodbit;
0711
0712 BOOST_TRY
0713 {
0714 typename std::basic_istream<CharT, Traits>::sentry ipfx(is);
0715 if (bool(ipfx))
0716 {
0717 if (!std::has_facet<time_point_get<CharT> >(is.getloc()))
0718 {
0719 time_point_get<CharT> ().get(is, std::istreambuf_iterator<CharT, Traits>(), is, err, tp);
0720 }
0721 else
0722 {
0723 std::use_facet<time_point_get<CharT> >(is.getloc()).get(is, std::istreambuf_iterator<CharT, Traits>(), is,
0724 err, tp);
0725 }
0726 }
0727 }
0728 BOOST_CATCH (...)
0729 {
0730 bool flag = false;
0731 BOOST_TRY
0732 {
0733 is.setstate(std::ios_base::failbit);
0734 }
0735 BOOST_CATCH (const std::ios_base::failure& )
0736 {
0737 flag = true;
0738 }
0739 BOOST_CATCH_END
0740 if (flag) throw;
0741 }
0742 BOOST_CATCH_END
0743 if (err) is.setstate(err);
0744 return is;
0745 }
0746
0747
0748 namespace detail
0749 {
0750
0751
0752
0753 inline int32_t is_leap(int32_t year)
0754 {
0755 if(year % 400 == 0)
0756 return 1;
0757 if(year % 100 == 0)
0758 return 0;
0759 if(year % 4 == 0)
0760 return 1;
0761 return 0;
0762 }
0763 inline int32_t days_from_0(int32_t year)
0764 {
0765 year--;
0766 return 365 * year + (year / 400) - (year/100) + (year / 4);
0767 }
0768 inline int32_t days_from_1970(int32_t year)
0769 {
0770 static const int32_t days_from_0_to_1970 = days_from_0(1970);
0771 return days_from_0(year) - days_from_0_to_1970;
0772 }
0773 inline int32_t days_from_1jan(int32_t year,int32_t month,int32_t day)
0774 {
0775 static const int32_t days[2][12] =
0776 {
0777 { 0,31,59,90,120,151,181,212,243,273,304,334},
0778 { 0,31,60,91,121,152,182,213,244,274,305,335}
0779 };
0780
0781 return days[is_leap(year)][month-1] + day - 1;
0782 }
0783
0784 inline time_t internal_timegm(std::tm const *t)
0785 {
0786 int year = t->tm_year + 1900;
0787 int month = t->tm_mon;
0788 if(month > 11)
0789 {
0790 year += month/12;
0791 month %= 12;
0792 }
0793 else if(month < 0)
0794 {
0795 int years_diff = (-month + 11)/12;
0796 year -= years_diff;
0797 month+=12 * years_diff;
0798 }
0799 month++;
0800 int day = t->tm_mday;
0801 int day_of_year = days_from_1jan(year,month,day);
0802 int days_since_epoch = days_from_1970(year) + day_of_year ;
0803
0804 time_t seconds_in_day = 3600 * 24;
0805 time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;
0806
0807 return result;
0808 }
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820 inline unsigned days_before_years(int32_t y)
0821 {
0822 return y * 365 + y / 4 - y / 100 + y / 400;
0823 }
0824
0825
0826
0827
0828 template <class Int>
0829
0830 void
0831 inline civil_from_days(Int z, Int& y, unsigned& m, unsigned& d) BOOST_NOEXCEPT
0832 {
0833 BOOST_STATIC_ASSERT_MSG(std::numeric_limits<unsigned>::digits >= 18,
0834 "This algorithm has not been ported to a 16 bit unsigned integer");
0835 BOOST_STATIC_ASSERT_MSG(std::numeric_limits<Int>::digits >= 20,
0836 "This algorithm has not been ported to a 16 bit signed integer");
0837 z += 719468;
0838 const Int era = (z >= 0 ? z : z - 146096) / 146097;
0839 const unsigned doe = static_cast<unsigned>(z - era * 146097);
0840 const unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365;
0841 y = static_cast<Int>(yoe) + era * 400;
0842 const unsigned doy = doe - (365*yoe + yoe/4 - yoe/100);
0843 const unsigned mp = (5*doy + 2)/153;
0844 d = doy - (153*mp+2)/5 + 1;
0845 m = mp + (mp < 10 ? 3 : -9);
0846 y += (m <= 2);
0847 --m;
0848 }
0849 inline std::tm * internal_gmtime(std::time_t const* t, std::tm *tm)
0850 {
0851 if (t==0) return 0;
0852 if (tm==0) return 0;
0853
0854 #if 0
0855 static const unsigned char
0856 day_of_year_month[2][366] =
0857 {
0858 { 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 },
0859
0860 { 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
0861
0862 } };
0863
0864 static const int32_t days_in_year_before[2][13] =
0865 {
0866 { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 },
0867 { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }
0868 };
0869 #endif
0870
0871 const time_t seconds_in_day = 3600 * 24;
0872 int32_t days_since_epoch = static_cast<int32_t>(*t / seconds_in_day);
0873 int32_t hms = static_cast<int32_t>(*t - seconds_in_day*days_since_epoch);
0874 if (hms < 0) {
0875 days_since_epoch-=1;
0876 hms = seconds_in_day+hms;
0877 }
0878
0879 #if 0
0880 int32_t x = days_since_epoch;
0881 int32_t y = static_cast<int32_t> (static_cast<long long> (x + 2) * 400
0882 / 146097);
0883 const int32_t ym1 = y - 1;
0884 int32_t doy = x - days_before_years(y);
0885 const int32_t doy1 = x - days_before_years(ym1);
0886 const int32_t N = std::numeric_limits<int>::digits - 1;
0887 const int32_t mask1 = doy >> N;
0888 const int32_t mask0 = ~mask1;
0889 doy = (doy & mask0) | (doy1 & mask1);
0890 y = (y & mask0) | (ym1 & mask1);
0891
0892 y += 70;
0893 tm->tm_year=y;
0894 const int32_t leap = is_leap(y);
0895 tm->tm_mon = day_of_year_month[leap][doy]-1;
0896 tm->tm_mday = doy - days_in_year_before[leap][tm->tm_mon] ;
0897 #else
0898 int32_t y;
0899 unsigned m, d;
0900 civil_from_days(days_since_epoch, y, m, d);
0901 tm->tm_year=y-1900; tm->tm_mon=m; tm->tm_mday=d;
0902 #endif
0903
0904 tm->tm_hour = hms / 3600;
0905 const int ms = hms % 3600;
0906 tm->tm_min = ms / 60;
0907 tm->tm_sec = ms % 60;
0908
0909 tm->tm_isdst = -1;
0910 (void)mktime(tm);
0911 return tm;
0912 }
0913
0914 }
0915 #ifndef BOOST_CHRONO_NO_UTC_TIMEPOINT
0916
0917 #if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
0918
0919 template <class CharT, class Traits, class Duration>
0920 std::basic_ostream<CharT, Traits>&
0921 operator<<(std::basic_ostream<CharT, Traits>& os, const time_point<system_clock, Duration>& tp)
0922 {
0923 typename std::basic_ostream<CharT, Traits>::sentry ok(os);
0924 if (bool(ok))
0925 {
0926 bool failed = false;
0927 BOOST_TRY
0928 {
0929 const CharT* pb = 0;
0930 const CharT* pe = pb;
0931 std::basic_string<CharT> fmt = get_time_fmt<CharT> (os);
0932 pb = fmt.data();
0933 pe = pb + fmt.size();
0934
0935 timezone tz = get_timezone(os);
0936 std::locale loc = os.getloc();
0937 time_t t = system_clock::to_time_t(time_point_cast<system_clock::duration>(tp));
0938 std::tm tm;
0939 std::memset(&tm, 0, sizeof(std::tm));
0940 if (tz == timezone::local)
0941 {
0942 #if defined BOOST_WINDOWS && ! defined(__CYGWIN__)
0943 #if BOOST_MSVC < 1400
0944 std::tm *tmp = 0;
0945 if ((tmp=localtime(&t)) == 0)
0946 failed = true;
0947 else
0948 tm =*tmp;
0949 # else
0950 if (localtime_s(&tm, &t) != 0) failed = true;
0951 # endif
0952 #else
0953 if (localtime_r(&t, &tm) == 0) failed = true;
0954 #endif
0955 }
0956 else
0957 {
0958 #if defined BOOST_CHRONO_INTERNAL_GMTIME
0959 if (detail::internal_gmtime(&t, &tm) == 0) failed = true;
0960
0961 #elif defined BOOST_WINDOWS && ! defined(__CYGWIN__)
0962 std::tm *tmp = 0;
0963 if((tmp = gmtime(&t)) == 0)
0964 failed = true;
0965 else
0966 tm = *tmp;
0967 #else
0968 if (gmtime_r(&t, &tm) == 0) failed = true;
0969 tm.tm_isdst = -1;
0970 (void)mktime(&tm);
0971
0972 #endif
0973
0974 }
0975 if (!failed)
0976 {
0977 const std::time_put<CharT>& tpf = std::use_facet<std::time_put<CharT> >(loc);
0978 if (pb == pe)
0979 {
0980 CharT pattern[] =
0981 { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' };
0982 pb = pattern;
0983 pe = pb + sizeof (pattern) / sizeof(CharT);
0984 failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
0985 if (!failed)
0986 {
0987 duration<fractional_seconds> d = tp - system_clock::from_time_t(t) + seconds(tm.tm_sec);
0988 if (d.count() < 10) os << CharT('0');
0989
0990
0991
0992 std::ios::fmtflags flgs = os.flags();
0993 os.setf(std::ios::fixed, std::ios::floatfield);
0994
0995
0996
0997 os.precision(9);
0998 os << d.count();
0999
1000
1001
1002 os.flags(flgs);
1003 if (tz == timezone::local)
1004 {
1005 CharT sub_pattern[] =
1006 { ' ', '%', 'z' };
1007 pb = sub_pattern;
1008 pe = pb + +sizeof (sub_pattern) / sizeof(CharT);
1009 failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
1010 }
1011 else
1012 {
1013 CharT sub_pattern[] =
1014 { ' ', '+', '0', '0', '0', '0', 0 };
1015 os << sub_pattern;
1016 }
1017 }
1018 }
1019 else
1020 {
1021 failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
1022 }
1023 }
1024 }
1025 BOOST_CATCH (...)
1026 {
1027 failed = true;
1028 }
1029 BOOST_CATCH_END
1030 if (failed)
1031 {
1032 os.setstate(std::ios_base::failbit | std::ios_base::badbit);
1033 }
1034 }
1035 return os;
1036 }
1037 #endif
1038
1039 namespace detail
1040 {
1041
1042 template <class CharT, class InputIterator>
1043 minutes extract_z(InputIterator& b, InputIterator e, std::ios_base::iostate& err, const std::ctype<CharT>& ct)
1044 {
1045 int min = 0;
1046 if (b != e)
1047 {
1048 char cn = ct.narrow(*b, 0);
1049 if (cn != '+' && cn != '-')
1050 {
1051 err |= std::ios_base::failbit;
1052 return minutes(0);
1053 }
1054 int sn = cn == '-' ? -1 : 1;
1055 int hr = 0;
1056 for (int i = 0; i < 2; ++i)
1057 {
1058 if (++b == e)
1059 {
1060 err |= std::ios_base::eofbit | std::ios_base::failbit;
1061 return minutes(0);
1062 }
1063 cn = ct.narrow(*b, 0);
1064 if (! ('0' <= cn && cn <= '9'))
1065 {
1066 err |= std::ios_base::failbit;
1067 return minutes(0);
1068 }
1069 hr = hr * 10 + cn - '0';
1070 }
1071 for (int i = 0; i < 2; ++i)
1072 {
1073 if (++b == e)
1074 {
1075 err |= std::ios_base::eofbit | std::ios_base::failbit;
1076 return minutes(0);
1077 }
1078 cn = ct.narrow(*b, 0);
1079 if (! ('0' <= cn && cn <= '9'))
1080 {
1081 err |= std::ios_base::failbit;
1082 return minutes(0);
1083 }
1084 min = min * 10 + cn - '0';
1085 }
1086 if (++b == e) {
1087 err |= std::ios_base::eofbit;
1088 }
1089 min += hr * 60;
1090 min *= sn;
1091 }
1092 else
1093 {
1094 err |= std::ios_base::eofbit | std::ios_base::failbit;
1095 }
1096 return minutes(min);
1097 }
1098
1099 }
1100
1101 #if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
1102
1103 template <class CharT, class Traits, class Duration>
1104 std::basic_istream<CharT, Traits>&
1105 operator>>(std::basic_istream<CharT, Traits>& is, time_point<system_clock, Duration>& tp)
1106 {
1107 typename std::basic_istream<CharT, Traits>::sentry ok(is);
1108 if (bool(ok))
1109 {
1110 std::ios_base::iostate err = std::ios_base::goodbit;
1111 BOOST_TRY
1112 {
1113 const CharT* pb = 0;
1114 const CharT* pe = pb;
1115 std::basic_string<CharT> fmt = get_time_fmt<CharT> (is);
1116 pb = fmt.data();
1117 pe = pb + fmt.size();
1118
1119 timezone tz = get_timezone(is);
1120 std::locale loc = is.getloc();
1121 const std::time_get<CharT>& tg = std::use_facet<std::time_get<CharT> >(loc);
1122 const std::ctype<CharT>& ct = std::use_facet<std::ctype<CharT> >(loc);
1123 tm tm;
1124 std::memset(&tm, 0, sizeof(std::tm));
1125
1126 typedef std::istreambuf_iterator<CharT, Traits> It;
1127 if (pb == pe)
1128 {
1129 CharT pattern[] =
1130 { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' };
1131 pb = pattern;
1132 pe = pb + sizeof (pattern) / sizeof(CharT);
1133
1134 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
1135 const detail::time_get<CharT>& dtg(tg);
1136 dtg.get(is, 0, is, err, &tm, pb, pe);
1137 #else
1138 tg.get(is, 0, is, err, &tm, pb, pe);
1139 #endif
1140 if (err & std::ios_base::failbit) goto exit;
1141 fractional_seconds sec;
1142 CharT c = CharT();
1143 std::ios::fmtflags flgs = is.flags();
1144 is.setf(std::ios::fixed, std::ios::floatfield);
1145 is.precision(9);
1146 is >> sec;
1147 is.flags(flgs);
1148 if (is.fail())
1149 {
1150 err |= std::ios_base::failbit;
1151 goto exit;
1152 }
1153 It i(is);
1154 It eof;
1155 c = *i;
1156 if (++i == eof || c != ' ')
1157 {
1158 err |= std::ios_base::failbit;
1159 goto exit;
1160 }
1161 minutes min = detail::extract_z(i, eof, err, ct);
1162
1163 if (err & std::ios_base::failbit) goto exit;
1164 time_t t;
1165
1166 #if defined BOOST_CHRONO_INTERNAL_TIMEGM
1167 t = detail::internal_timegm(&tm);
1168 #else
1169 t = timegm(&tm);
1170 #endif
1171 tp = time_point_cast<Duration>(
1172 system_clock::from_time_t(t) - min + round<system_clock::duration> (duration<fractional_seconds> (sec))
1173 );
1174 }
1175 else
1176 {
1177 const CharT z[2] =
1178 { '%', 'z' };
1179 const CharT* fz = std::search(pb, pe, z, z + 2);
1180 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
1181 const detail::time_get<CharT>& dtg(tg);
1182 dtg.get(is, 0, is, err, &tm, pb, fz);
1183 #else
1184 tg.get(is, 0, is, err, &tm, pb, fz);
1185 #endif
1186 minutes minu(0);
1187 if (fz != pe)
1188 {
1189 if (err != std::ios_base::goodbit)
1190 {
1191 err |= std::ios_base::failbit;
1192 goto exit;
1193 }
1194 It i(is);
1195 It eof;
1196 minu = detail::extract_z(i, eof, err, ct);
1197 if (err & std::ios_base::failbit) goto exit;
1198 if (fz + 2 != pe)
1199 {
1200 if (err != std::ios_base::goodbit)
1201 {
1202 err |= std::ios_base::failbit;
1203 goto exit;
1204 }
1205 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
1206 const detail::time_get<CharT>& dtg(tg);
1207 dtg.get(is, 0, is, err, &tm, fz + 2, pe);
1208 #else
1209 tg.get(is, 0, is, err, &tm, fz + 2, pe);
1210 #endif
1211 if (err & std::ios_base::failbit) goto exit;
1212 }
1213 }
1214 tm.tm_isdst = -1;
1215 time_t t;
1216 if (tz == timezone::utc || fz != pe)
1217 {
1218 #if defined BOOST_CHRONO_INTERNAL_TIMEGM
1219 t = detail::internal_timegm(&tm);
1220 #else
1221 t = timegm(&tm);
1222 #endif
1223 }
1224 else
1225 {
1226 t = mktime(&tm);
1227 }
1228 tp = time_point_cast<Duration>(
1229 system_clock::from_time_t(t) - minu
1230 );
1231 }
1232 }
1233 BOOST_CATCH (...)
1234 {
1235 err |= std::ios_base::badbit | std::ios_base::failbit;
1236 }
1237 BOOST_CATCH_END
1238 exit: is.setstate(err);
1239 }
1240 return is;
1241 }
1242
1243 #endif
1244 #endif
1245 }
1246
1247 }
1248
1249 #endif