diff options
Diffstat (limited to 'boost/date_time')
23 files changed, 322 insertions, 218 deletions
diff --git a/boost/date_time/adjust_functors.hpp b/boost/date_time/adjust_functors.hpp index 7911b7971e..ec2a707659 100644 --- a/boost/date_time/adjust_functors.hpp +++ b/boost/date_time/adjust_functors.hpp @@ -23,17 +23,12 @@ namespace date_time { public: typedef typename date_type::duration_type duration_type; day_functor(int f) : f_(f) {} - duration_type get_offset(const date_type& d) const + duration_type get_offset(const date_type&) const { - // why is 'd' a parameter??? - // fix compiler warnings - d.year(); return duration_type(f_); } - duration_type get_neg_offset(const date_type& d) const + duration_type get_neg_offset(const date_type&) const { - // fix compiler warnings - d.year(); return duration_type(-f_); } private: @@ -129,18 +124,13 @@ namespace date_time { typedef typename date_type::duration_type duration_type; typedef typename date_type::calendar_type calendar_type; week_functor(int f) : f_(f) {} - duration_type get_offset(const date_type& d) const + duration_type get_offset(const date_type&) const { - // why is 'd' a parameter??? - // fix compiler warnings - d.year(); - return duration_type(f_*calendar_type::days_in_week()); + return duration_type(f_*static_cast<int>(calendar_type::days_in_week())); } - duration_type get_neg_offset(const date_type& d) const + duration_type get_neg_offset(const date_type&) const { - // fix compiler warnings - d.year(); - return duration_type(-f_*calendar_type::days_in_week()); + return duration_type(-f_*static_cast<int>(calendar_type::days_in_week())); } private: int f_; diff --git a/boost/date_time/c_local_time_adjustor.hpp b/boost/date_time/c_local_time_adjustor.hpp index aa563122b1..9170aa6687 100644 --- a/boost/date_time/c_local_time_adjustor.hpp +++ b/boost/date_time/c_local_time_adjustor.hpp @@ -17,6 +17,7 @@ #include <boost/throw_exception.hpp> #include <boost/date_time/compiler_config.hpp> #include <boost/date_time/c_time.hpp> +#include <boost/numeric/conversion/cast.hpp> namespace boost { namespace date_time { @@ -42,12 +43,14 @@ namespace date_time { } date_duration_type dd = t.date() - time_t_start_day; time_duration_type td = t.time_of_day(); - std::time_t t2 = static_cast<std::time_t>(dd.days())*86400 + - static_cast<std::time_t>(td.hours())*3600 + - static_cast<std::time_t>(td.minutes())*60 + - td.seconds(); + uint64_t t2 = static_cast<uint64_t>(dd.days())*86400 + + static_cast<uint64_t>(td.hours())*3600 + + static_cast<uint64_t>(td.minutes())*60 + + td.seconds(); + // detect y2038 issue and throw instead of proceed with bad time + std::time_t tv = boost::numeric_cast<std::time_t>(t2); std::tm tms, *tms_ptr; - tms_ptr = c_time::localtime(&t2, &tms); + tms_ptr = c_time::localtime(&tv, &tms); date_type d(static_cast<unsigned short>(tms_ptr->tm_year + 1900), static_cast<unsigned short>(tms_ptr->tm_mon + 1), static_cast<unsigned short>(tms_ptr->tm_mday)); diff --git a/boost/date_time/date_duration.hpp b/boost/date_time/date_duration.hpp index 22a05ed123..82c75b42a0 100644 --- a/boost/date_time/date_duration.hpp +++ b/boost/date_time/date_duration.hpp @@ -52,6 +52,10 @@ namespace date_time { { return days_; } + special_values as_special() const + { + return days_.as_special(); + } bool is_special()const { return days_.is_special(); diff --git a/boost/date_time/date_formatting.hpp b/boost/date_time/date_formatting.hpp index d4ca3dd27c..c1b69a8c79 100644 --- a/boost/date_time/date_formatting.hpp +++ b/boost/date_time/date_formatting.hpp @@ -11,6 +11,7 @@ #include "boost/date_time/iso_format.hpp" #include "boost/date_time/compiler_config.hpp" +#include <boost/io/ios_state.hpp> #include <string> #include <sstream> #include <iomanip> @@ -51,6 +52,7 @@ namespace date_time { } case month_as_integer: { + boost::io::basic_ios_fill_saver<charT> ifs(os); os << std::setw(2) << std::setfill(os.widen('0')) << month.as_number(); break; } diff --git a/boost/date_time/date_formatting_locales.hpp b/boost/date_time/date_formatting_locales.hpp index 2c17c055cd..a1daad33ae 100644 --- a/boost/date_time/date_formatting_locales.hpp +++ b/boost/date_time/date_formatting_locales.hpp @@ -17,6 +17,7 @@ #include "boost/date_time/iso_format.hpp" #include "boost/date_time/date_names_put.hpp" #include "boost/date_time/parse_format_base.hpp" +#include <boost/io/ios_state.hpp> //#include <string> #include <sstream> #include <iomanip> @@ -56,8 +57,8 @@ namespace date_time { } case month_as_integer: { - charT fill_char = '0'; - os << std::setw(2) << std::setfill(fill_char) << month.as_number(); + boost::io::basic_ios_fill_saver<charT> ifs(os); + os << std::setw(2) << std::setfill(os.widen('0')) << month.as_number(); break; } @@ -132,8 +133,8 @@ namespace date_time { ostream_type& os, const facet_type& f) { + boost::io::basic_ios_fill_saver<charT> ifs(os); std::ostreambuf_iterator<charT> oitr(os); - charT fill_char = '0'; switch (f.date_order()) { case ymd_order_iso: { os << ymd.year; @@ -144,7 +145,7 @@ namespace date_time { if (f.has_date_sep_chars()) { f.day_sep_char(oitr); } - os << std::setw(2) << std::setfill(fill_char) + os << std::setw(2) << std::setfill(os.widen('0')) << ymd.day; break; } @@ -153,7 +154,7 @@ namespace date_time { if (f.has_date_sep_chars()) { f.day_sep_char(oitr); } - os << std::setw(2) << std::setfill(fill_char) + os << std::setw(2) << std::setfill(os.widen('0')) << ymd.day; if (f.has_date_sep_chars()) { f.month_sep_char(oitr); @@ -162,7 +163,7 @@ namespace date_time { break; } case ymd_order_dmy: { - os << std::setw(2) << std::setfill(fill_char) + os << std::setw(2) << std::setfill(os.widen('0')) << ymd.day; if (f.has_date_sep_chars()) { f.day_sep_char(oitr); diff --git a/boost/date_time/format_date_parser.hpp b/boost/date_time/format_date_parser.hpp index a40dee6fb6..0602e90f3f 100644 --- a/boost/date_time/format_date_parser.hpp +++ b/boost/date_time/format_date_parser.hpp @@ -659,8 +659,6 @@ class format_date_parser string_type format_str, match_results& mr) const { - bool use_current_char = false; - // skip leading whitespace while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } @@ -701,12 +699,7 @@ class format_date_parser } else { //skip past chars in format and in buffer itr++; - if (use_current_char) { - use_current_char = false; - } - else { - sitr++; - } + sitr++; } } diff --git a/boost/date_time/gregorian/greg_facet.hpp b/boost/date_time/gregorian/greg_facet.hpp index f720aac3bf..5352df1398 100644 --- a/boost/date_time/gregorian/greg_facet.hpp +++ b/boost/date_time/gregorian/greg_facet.hpp @@ -13,6 +13,7 @@ #include <boost/date_time/gregorian/gregorian_types.hpp> #include <boost/date_time/date_formatting_locales.hpp> // sets BOOST_DATE_TIME_NO_LOCALE #include <boost/date_time/gregorian/parsers.hpp> +#include <boost/io/ios_state.hpp> //This file is basically commented out if locales are not supported #ifndef BOOST_DATE_TIME_NO_LOCALE @@ -75,9 +76,9 @@ namespace gregorian { greg_month_formatter::format_month(m, os, f); } - else { //default to numeric - charT fill_char = '0'; - os << std::setw(2) << std::setfill(fill_char) << m.as_number(); + else { // default to numeric + boost::io::basic_ios_fill_saver<charT> ifs(os); + os << std::setw(2) << std::setfill(os.widen('0')) << m.as_number(); } return os; @@ -142,7 +143,8 @@ namespace gregorian { std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const partial_date& pd) { - os << std::setw(2) << std::setfill('0') << pd.day() << ' ' + boost::io::basic_ios_fill_saver<charT> ifs(os); + os << std::setw(2) << std::setfill(os.widen('0')) << pd.day() << ' ' << pd.month().as_short_string() ; return os; } diff --git a/boost/date_time/gregorian/greg_year.hpp b/boost/date_time/gregorian/greg_year.hpp index 3245518474..a278bdaa03 100644 --- a/boost/date_time/gregorian/greg_year.hpp +++ b/boost/date_time/gregorian/greg_year.hpp @@ -21,19 +21,19 @@ namespace gregorian { struct BOOST_SYMBOL_VISIBLE bad_year : public std::out_of_range { bad_year() : - std::out_of_range(std::string("Year is out of valid range: 1400..10000")) + std::out_of_range(std::string("Year is out of valid range: 1400..9999")) {} }; //! Policy class that declares error handling gregorian year type - typedef CV::simple_exception_policy<unsigned short, 1400, 10000, bad_year> greg_year_policies; + typedef CV::simple_exception_policy<unsigned short, 1400, 9999, bad_year> greg_year_policies; //! Generated representation for gregorian year typedef CV::constrained_value<greg_year_policies> greg_year_rep; - //! Represent a year (range 1400 - 10000) + //! Represent a year (range 1400 - 9999) /*! This small class allows for simple conversion an integer value into a year for the gregorian calendar. This currently only allows a - range of 1400 to 10000. Both ends of the range are a bit arbitrary + range of 1400 to 9999. Both ends of the range are a bit arbitrary at the moment, but they are the limits of current testing of the library. As such they may be increased in the future. */ diff --git a/boost/date_time/gregorian/gregorian_io.hpp b/boost/date_time/gregorian/gregorian_io.hpp index e0a23f3269..49e5d41ed8 100644 --- a/boost/date_time/gregorian/gregorian_io.hpp +++ b/boost/date_time/gregorian/gregorian_io.hpp @@ -77,14 +77,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, d); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, d); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, d); @@ -138,14 +138,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, dd); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, dd); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, dd); @@ -202,14 +202,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, dp); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, dp); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, dp); @@ -261,14 +261,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, m); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, m); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, m); @@ -318,14 +318,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, wd); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, wd); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, wd); @@ -359,14 +359,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, gd); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, gd); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, gd); @@ -400,14 +400,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, gy); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, gy); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, gy); @@ -458,14 +458,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, pd); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, pd); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, pd); @@ -515,14 +515,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, nday); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, nday); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, nday); @@ -573,14 +573,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fkd); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, fkd); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, fkd); @@ -631,14 +631,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, lkd); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, lkd); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, lkd); @@ -690,14 +690,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fka); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, fka); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, fka); @@ -749,14 +749,14 @@ namespace gregorian { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::date_input_facet<date, CharT> date_input_facet; + typedef typename date_time::date_input_facet<date, CharT> date_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<date_input_facet>(is.getloc())) { - std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fkb); + if(std::has_facet<date_input_facet_local>(is.getloc())) { + std::use_facet<date_input_facet_local>(is.getloc()).get(sit, str_end, is, fkb); } else { - date_input_facet* f = new date_input_facet(); + date_input_facet_local* f = new date_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, fkb); diff --git a/boost/date_time/int_adapter.hpp b/boost/date_time/int_adapter.hpp index 39210864ca..6ee7712fab 100644 --- a/boost/date_time/int_adapter.hpp +++ b/boost/date_time/int_adapter.hpp @@ -18,6 +18,12 @@ # include <ostream> #endif +#if defined(BOOST_MSVC) +#pragma warning(push) +// conditional expression is constant +#pragma warning(disable: 4127) +#endif + namespace boost { namespace date_time { @@ -136,9 +142,7 @@ public: } bool operator==(const int& rhs) const { - // quiets compiler warnings - bool is_signed = std::numeric_limits<int_type>::is_signed; - if(!is_signed) + if(!std::numeric_limits<int_type>::is_signed) { if(is_neg_inf(value_) && rhs == 0) { @@ -153,9 +157,7 @@ public: } bool operator!=(const int& rhs) const { - // quiets compiler warnings - bool is_signed = std::numeric_limits<int_type>::is_signed; - if(!is_signed) + if(!std::numeric_limits<int_type>::is_signed) { if(is_neg_inf(value_) && rhs == 0) { @@ -171,8 +173,7 @@ public: bool operator<(const int& rhs) const { // quiets compiler warnings - bool is_signed = std::numeric_limits<int_type>::is_signed; - if(!is_signed) + if(!std::numeric_limits<int_type>::is_signed) { if(is_neg_inf(value_) && rhs == 0) { @@ -414,18 +415,10 @@ private: //! Assumes at least 'this' or 'rhs' is a special value int_adapter mult_div_specials(const int_adapter& rhs)const { - int min_value; - // quiets compiler warnings - bool is_signed = std::numeric_limits<int_type>::is_signed; - if(is_signed) { - min_value = 0; - } - else { - min_value = 1;// there is no zero with unsigned - } if(this->is_nan() || rhs.is_nan()) { return int_adapter<int_type>(not_a_number()); } + BOOST_CONSTEXPR_OR_CONST int min_value = std::numeric_limits<int_type>::is_signed ? 0 : 1; if((*this > 0 && rhs > 0) || (*this < min_value && rhs < min_value)) { return int_adapter<int_type>(pos_infinity()); } @@ -443,18 +436,10 @@ private: //! Assumes 'this' is a special value int_adapter mult_div_specials(const int& rhs) const { - int min_value; - // quiets compiler warnings - bool is_signed = std::numeric_limits<int_type>::is_signed; - if(is_signed) { - min_value = 0; - } - else { - min_value = 1;// there is no zero with unsigned - } if(this->is_nan()) { return int_adapter<int_type>(not_a_number()); } + BOOST_CONSTEXPR_OR_CONST int min_value = std::numeric_limits<int_type>::is_signed ? 0 : 1; if((*this > 0 && rhs > 0) || (*this < min_value && rhs < 0)) { return int_adapter<int_type>(pos_infinity()); } @@ -504,6 +489,8 @@ private: } } //namespace date_time - +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif #endif diff --git a/boost/date_time/local_time/custom_time_zone.hpp b/boost/date_time/local_time/custom_time_zone.hpp index b89218a659..f82d87a7d7 100644 --- a/boost/date_time/local_time/custom_time_zone.hpp +++ b/boost/date_time/local_time/custom_time_zone.hpp @@ -154,7 +154,6 @@ namespace local_time { } private: time_zone_names zone_names_; - bool has_dst_; time_duration_type base_utc_offset_; dst_adjustment_offsets dst_offsets_; boost::shared_ptr<dst_calc_rule> dst_calc_rules_; diff --git a/boost/date_time/period_formatter.hpp b/boost/date_time/period_formatter.hpp index 0cce32a68a..9610612834 100644 --- a/boost/date_time/period_formatter.hpp +++ b/boost/date_time/period_formatter.hpp @@ -114,18 +114,19 @@ namespace boost { namespace date_time { { m_range_option = option; } - void delimiter_strings(const string_type& , - const string_type& , - const string_type& , - const string_type& ) + + //! Change the delimiter strings + void delimiter_strings(const string_type& separator, + const string_type& start_delim, + const string_type& open_end_delim, + const string_type& closed_end_delim) { - m_period_separator; - m_period_start_delimeter; - m_open_range_end_delimeter; - m_closed_range_end_delimeter; + m_period_separator = separator; + m_period_start_delimeter = start_delim; + m_open_range_end_delimeter = open_end_delim; + m_closed_range_end_delimeter = closed_end_delim; } - //! Generic code to output a period -- no matter the period type. /*! This generic code will output any period using a facet to * to output the 'elements'. For example, in the case of a date_period diff --git a/boost/date_time/posix_time/posix_time_duration.hpp b/boost/date_time/posix_time/posix_time_duration.hpp index 1143cedb57..c7ec57e8aa 100644 --- a/boost/date_time/posix_time/posix_time_duration.hpp +++ b/boost/date_time/posix_time/posix_time_duration.hpp @@ -9,42 +9,54 @@ * $Date$ */ +#include <boost/core/enable_if.hpp> #include <boost/date_time/compiler_config.hpp> #include <boost/date_time/posix_time/posix_time_config.hpp> +#include <boost/numeric/conversion/cast.hpp> +#include <boost/type_traits/is_integral.hpp> namespace boost { namespace posix_time { //! Allows expression of durations as an hour count + //! The argument must be an integral type /*! \ingroup time_basics */ class BOOST_SYMBOL_VISIBLE hours : public time_duration { public: - explicit hours(long h) : - time_duration(static_cast<hour_type>(h),0,0) + template <typename T> + explicit hours(T const& h, + typename boost::enable_if<boost::is_integral<T>, void>::type* = 0) : + time_duration(numeric_cast<hour_type>(h), 0, 0) {} }; //! Allows expression of durations as a minute count + //! The argument must be an integral type /*! \ingroup time_basics */ class BOOST_SYMBOL_VISIBLE minutes : public time_duration { public: - explicit minutes(long m) : - time_duration(0,static_cast<min_type>(m),0) + template <typename T> + explicit minutes(T const& m, + typename boost::enable_if<boost::is_integral<T>, void>::type* = 0) : + time_duration(0, numeric_cast<min_type>(m),0) {} }; //! Allows expression of durations as a seconds count + //! The argument must be an integral type /*! \ingroup time_basics */ class BOOST_SYMBOL_VISIBLE seconds : public time_duration { public: - explicit seconds(long s) : - time_duration(0,0,static_cast<sec_type>(s)) + template <typename T> + explicit seconds(T const& s, + typename boost::enable_if<boost::is_integral<T>, void>::type* = 0) : + time_duration(0,0, numeric_cast<sec_type>(s)) {} }; @@ -70,12 +82,8 @@ namespace posix_time { typedef date_time::subsecond_duration<time_duration,1000000000> nanosec; typedef date_time::subsecond_duration<time_duration,1000000000> nanoseconds; - #endif - - - } }//namespace posix_time diff --git a/boost/date_time/posix_time/posix_time_io.hpp b/boost/date_time/posix_time/posix_time_io.hpp index 45c338b220..90b02a6919 100644 --- a/boost/date_time/posix_time/posix_time_io.hpp +++ b/boost/date_time/posix_time/posix_time_io.hpp @@ -74,13 +74,13 @@ namespace posix_time { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet; + typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<time_input_facet>(is.getloc())) { - std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, pt); + if(std::has_facet<time_input_facet_local>(is.getloc())) { + std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, pt); } else { - time_input_facet* f = new time_input_facet(); + time_input_facet_local* f = new time_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, pt); @@ -141,13 +141,13 @@ namespace posix_time { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet; + typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<time_input_facet>(is.getloc())) { - std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, tp); + if(std::has_facet<time_input_facet_local>(is.getloc())) { + std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, tp); } else { - time_input_facet* f = new time_input_facet(); + time_input_facet_local* f = new time_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, tp); @@ -205,13 +205,13 @@ namespace posix_time { typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); if (strm_sentry) { try { - typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet; + typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local; std::istreambuf_iterator<CharT,Traits> sit(is), str_end; - if(std::has_facet<time_input_facet>(is.getloc())) { - std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, td); + if(std::has_facet<time_input_facet_local>(is.getloc())) { + std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, td); } else { - time_input_facet* f = new time_input_facet(); + time_input_facet_local* f = new time_input_facet_local(); std::locale l = std::locale(is.getloc(), f); is.imbue(l); f->get(sit, str_end, is, td); diff --git a/boost/date_time/posix_time/time_serialize.hpp b/boost/date_time/posix_time/time_serialize.hpp index 8650ae1da9..71f60b3741 100644 --- a/boost/date_time/posix_time/time_serialize.hpp +++ b/boost/date_time/posix_time/time_serialize.hpp @@ -11,9 +11,10 @@ #include "boost/date_time/posix_time/posix_time.hpp" #include "boost/date_time/gregorian/greg_serialize.hpp" +#include "boost/numeric/conversion/cast.hpp" #include "boost/serialization/split_free.hpp" #include "boost/serialization/nvp.hpp" - +#include "boost/serialization/version.hpp" // macros to split serialize functions into save & load functions // NOTE: these macros define template functions in the boost::serialization namespace. @@ -22,6 +23,14 @@ BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::ptime) BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_duration) BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_period) +// Define versions for serialization compatibility +// alows the unit tests to make an older version to check compatibility +#ifndef BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION +#define BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION 1 +#endif + +BOOST_CLASS_VERSION(boost::posix_time::time_duration, BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION) + namespace boost { namespace serialization { @@ -33,10 +42,23 @@ namespace serialization { * types are hour_type, min_type, sec_type, and fractional_seconds_type * as defined in the time_duration class */ +template<class TimeResTraitsSize, class Archive> +void save_td(Archive& ar, const posix_time::time_duration& td) +{ + TimeResTraitsSize h = boost::numeric_cast<TimeResTraitsSize>(td.hours()); + TimeResTraitsSize m = boost::numeric_cast<TimeResTraitsSize>(td.minutes()); + TimeResTraitsSize s = boost::numeric_cast<TimeResTraitsSize>(td.seconds()); + posix_time::time_duration::fractional_seconds_type fs = td.fractional_seconds(); + ar & make_nvp("time_duration_hours", h); + ar & make_nvp("time_duration_minutes", m); + ar & make_nvp("time_duration_seconds", s); + ar & make_nvp("time_duration_fractional_seconds", fs); +} + template<class Archive> void save(Archive & ar, const posix_time::time_duration& td, - unsigned int /*version*/) + unsigned int version) { // serialize a bool so we know how to read this back in later bool is_special = td.is_special(); @@ -46,14 +68,13 @@ void save(Archive & ar, ar & make_nvp("sv_time_duration", s); } else { - posix_time::time_duration::hour_type h = td.hours(); - posix_time::time_duration::min_type m = td.minutes(); - posix_time::time_duration::sec_type s = td.seconds(); - posix_time::time_duration::fractional_seconds_type fs = td.fractional_seconds(); - ar & make_nvp("time_duration_hours", h); - ar & make_nvp("time_duration_minutes", m); - ar & make_nvp("time_duration_seconds", s); - ar & make_nvp("time_duration_fractional_seconds", fs); + // Write support for earlier versions allows for upgrade compatibility testing + // See load comments for version information + if (version == 0) { + save_td<int32_t>(ar, td); + } else { + save_td<int64_t>(ar, td); + } } } @@ -62,10 +83,24 @@ void save(Archive & ar, * types are hour_type, min_type, sec_type, and fractional_seconds_type * as defined in the time_duration class */ +template<class TimeResTraitsSize, class Archive> +void load_td(Archive& ar, posix_time::time_duration& td) +{ + TimeResTraitsSize h(0); + TimeResTraitsSize m(0); + TimeResTraitsSize s(0); + posix_time::time_duration::fractional_seconds_type fs(0); + ar & make_nvp("time_duration_hours", h); + ar & make_nvp("time_duration_minutes", m); + ar & make_nvp("time_duration_seconds", s); + ar & make_nvp("time_duration_fractional_seconds", fs); + td = posix_time::time_duration(h, m, s, fs); +} + template<class Archive> void load(Archive & ar, posix_time::time_duration & td, - unsigned int /*version*/) + unsigned int version) { bool is_special = false; ar & make_nvp("is_special", is_special); @@ -76,15 +111,25 @@ void load(Archive & ar, td = posix_time::time_duration(sv); } else { - posix_time::time_duration::hour_type h(0); - posix_time::time_duration::min_type m(0); - posix_time::time_duration::sec_type s(0); - posix_time::time_duration::fractional_seconds_type fs(0); - ar & make_nvp("time_duration_hours", h); - ar & make_nvp("time_duration_minutes", m); - ar & make_nvp("time_duration_seconds", s); - ar & make_nvp("time_duration_fractional_seconds", fs); - td = posix_time::time_duration(h,m,s,fs); + // Version "0" (Boost 1.65.1 or earlier, which used int32_t for day/hour/minute/second and + // therefore suffered from the year 2038 issue.) + // Version "0.5" (Boost 1.66.0 changed to std::time_t but did not increase the version; + // it was missed in the original change, all code reviews, and there were no + // static assertions to protect the code; further std::time_t can be 32-bit + // or 64-bit so it reduced portability. This makes 1.66.0 hard to handle...) + // Version "1" (Boost 1.67.0 or later uses int64_t and is properly versioned) + + // If the size of any of these items changes, a new version is needed. + BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::hour_type) == sizeof(boost::int64_t)); + BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::min_type) == sizeof(boost::int64_t)); + BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::sec_type) == sizeof(boost::int64_t)); + BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::fractional_seconds_type) == sizeof(boost::int64_t)); + + if (version == 0) { + load_td<int32_t>(ar, td); + } else { + load_td<int64_t>(ar, td); + } } } diff --git a/boost/date_time/special_values_parser.hpp b/boost/date_time/special_values_parser.hpp index e48ec5fda9..43748c74cd 100644 --- a/boost/date_time/special_values_parser.hpp +++ b/boost/date_time/special_values_parser.hpp @@ -34,14 +34,9 @@ namespace boost { namespace date_time { { public: typedef std::basic_string<charT> string_type; - //typedef std::basic_stringstream<charT> stringstream_type; + typedef std::basic_stringstream<charT> stringstream_type; typedef std::istreambuf_iterator<charT> stream_itr_type; - //typedef typename string_type::const_iterator const_itr; - //typedef typename date_type::year_type year_type; - //typedef typename date_type::month_type month_type; typedef typename date_type::duration_type duration_type; - //typedef typename date_type::day_of_week_type day_of_week_type; - //typedef typename date_type::day_type day_type; typedef string_parse_tree<charT> parse_tree_type; typedef typename parse_tree_type::parse_match_result_type match_results; typedef std::vector<std::basic_string<charT> > collection_type; @@ -101,11 +96,37 @@ namespace boost { namespace date_time { m_sv_strings = parse_tree_type(phrases, static_cast<int>(not_a_date_time)); } - /* Does not return a special_value because if the parsing fails, - * the return value will always be not_a_date_time - * (mr.current_match retains its default value of -1 on a failed - * parse and that casts to not_a_date_time). */ - //! Sets match_results.current_match to the corresponding special_value or -1 + //! The parser is expensive to create, and not thread-safe so it cannot be static + //! therefore given a string, determine if it is likely to be a special value. + //! A negative response is a definite no, whereas a positive is only likely and + //! match() should be called and return value checked. + //! \param[in] str the string to check + //! \returns false if it is definitely not a special value + static bool likely(const string_type& str) + { + if (!str.empty()) { + switch (str[0]) { + // See string definitions at the end of this class.. + case '+': + case '-': + case 'n': + case 'm': + return true; + + default: + break; + } + } + + return false; + } + + //! Given an input iterator, attempt to match it to a known special value + //! \param[in] sitr the start iterator + //! \param[in] str_end the end iterator + //! \param[out] mr the match result: + //! mr.current_match is set to the corresponding special_value or -1 + //! \returns whether something matched bool match(stream_itr_type& sitr, stream_itr_type& str_end, match_results& mr) const @@ -114,18 +135,6 @@ namespace boost { namespace date_time { m_sv_strings.match(sitr, str_end, mr, level); return (mr.current_match != match_results::PARSE_ERROR); } - /*special_values match(stream_itr_type& sitr, - stream_itr_type& str_end, - match_results& mr) const - { - unsigned int level = 0; - m_sv_strings.match(sitr, str_end, mr, level); - if(mr.current_match == match_results::PARSE_ERROR) { - throw std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"); - } - return static_cast<special_values>(mr.current_match); - }*/ - private: parse_tree_type m_sv_strings; diff --git a/boost/date_time/string_parse_tree.hpp b/boost/date_time/string_parse_tree.hpp index 9e977663fa..a241e8553c 100644 --- a/boost/date_time/string_parse_tree.hpp +++ b/boost/date_time/string_parse_tree.hpp @@ -25,7 +25,7 @@ struct parse_match_result { parse_match_result() : match_depth(0), - current_match(-1)// -1 is match_not-found value + current_match(PARSE_ERROR) {} typedef std::basic_string<charT> string_type; string_type remaining() const @@ -33,7 +33,7 @@ struct parse_match_result if (match_depth == cache.size()) { return string_type(); } - if (current_match == -1) { + if (current_match == PARSE_ERROR) { return cache; } //some of the cache was used return the rest @@ -56,7 +56,7 @@ struct parse_match_result string_type cache; unsigned short match_depth; short current_match; - enum PARSE_STATE { PARSE_ERROR= -1 }; + enum PARSE_STATE { PARSE_ERROR = -1 }; }; //for debug -- really only char streams... @@ -99,7 +99,8 @@ struct string_parse_tree * (Sun=0, Mon=1, ...) were a starting_point of one starts the * numbering at one (Jan=1, Feb=2, ...). The default is zero, * negative vaules are not allowed */ - string_parse_tree(collection_type names, unsigned int starting_point=0) + string_parse_tree(collection_type names, unsigned int starting_point=0) : + m_value(parse_match_result_type::PARSE_ERROR) { // iterate thru all the elements and build the tree unsigned short index = 0; @@ -113,7 +114,7 @@ struct string_parse_tree } - string_parse_tree(short value = -1) : + string_parse_tree(short value = parse_match_result_type::PARSE_ERROR) : m_value(value) {} ptree_coll m_next_chars; diff --git a/boost/date_time/time_duration.hpp b/boost/date_time/time_duration.hpp index fe4881e88b..67930cf8d3 100644 --- a/boost/date_time/time_duration.hpp +++ b/boost/date_time/time_duration.hpp @@ -9,12 +9,14 @@ * $Date$ */ +#include <boost/core/enable_if.hpp> #include <boost/cstdint.hpp> +#include <boost/date_time/compiler_config.hpp> +#include <boost/date_time/special_defs.hpp> +#include <boost/date_time/time_defs.hpp> #include <boost/operators.hpp> #include <boost/static_assert.hpp> -#include <boost/date_time/time_defs.hpp> -#include <boost/date_time/special_defs.hpp> -#include <boost/date_time/compiler_config.hpp> +#include <boost/type_traits/is_integral.hpp> namespace boost { namespace date_time { @@ -262,7 +264,7 @@ namespace date_time { //! Template for instantiating derived adjusting durations /* These templates are designed to work with multiples of - * 10 for frac_of_second and resoultion adjustment + * 10 for frac_of_second and resolution adjustment */ template<class base_duration, boost::int64_t frac_of_second> class BOOST_SYMBOL_VISIBLE subsecond_duration : public base_duration @@ -278,14 +280,15 @@ namespace date_time { BOOST_STATIC_CONSTANT(boost::int64_t, adjustment_ratio = (traits_type::ticks_per_second >= frac_of_second ? traits_type::ticks_per_second / frac_of_second : frac_of_second / traits_type::ticks_per_second)); public: - explicit subsecond_duration(boost::int64_t ss) : + // The argument (ss) must be an integral type + template <typename T> + explicit subsecond_duration(T const& ss, + typename boost::enable_if<boost::is_integral<T>, void>::type* = 0) : base_duration(impl_type(traits_type::ticks_per_second >= frac_of_second ? ss * adjustment_ratio : ss / adjustment_ratio)) { } }; - - } } //namespace date_time diff --git a/boost/date_time/time_facet.hpp b/boost/date_time/time_facet.hpp index 38b2ba7639..1e07093ffc 100644 --- a/boost/date_time/time_facet.hpp +++ b/boost/date_time/time_facet.hpp @@ -866,6 +866,7 @@ namespace date_time { break; // %s is the same as %S%f so we drop through into %f } + /* Falls through. */ case 'f': { // check for decimal, check special_values if missing @@ -1088,9 +1089,12 @@ namespace date_time { break; } case 'd': + case 'e': { try { - t_day = this->m_parser.parse_day_of_month(sitr, stream_end); + t_day = (*itr == 'd') ? + this->m_parser.parse_day_of_month(sitr, stream_end) : + this->m_parser.parse_var_day_of_month(sitr, stream_end); } catch(std::out_of_range&) { // base class for exception bad_day_of_month match_results mr; @@ -1136,6 +1140,7 @@ namespace date_time { // %s is the same as %S%f so we drop through into %f if we are // not at the end of the stream } + /* Falls through. */ case 'f': { // check for decimal, check SV if missing @@ -1227,7 +1232,7 @@ namespace date_time { date_type d(not_a_date_time); if (day_of_year > 0) { - d = date_type(static_cast<unsigned short>(t_year-1),12,31) + date_duration_type(day_of_year); + d = date_type(static_cast<unsigned short>(t_year),1,1) + date_duration_type(day_of_year-1); } else { d = date_type(t_year, t_month, t_day); @@ -1250,7 +1255,7 @@ namespace date_time { if((c == '-' || c == '+') && (*sitr != c)) { // was the first character consumed? mr.cache += c; } - this->m_sv_parser.match(sitr, stream_end, mr); + (void)this->m_sv_parser.match(sitr, stream_end, mr); if(mr.current_match == match_results::PARSE_ERROR) { std::string tmp = convert_string_type<char_type, char>(mr.cache); boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + tmp + "'")); diff --git a/boost/date_time/time_parsing.hpp b/boost/date_time/time_parsing.hpp index 6de4b7dbde..5fa7e8d2c5 100644 --- a/boost/date_time/time_parsing.hpp +++ b/boost/date_time/time_parsing.hpp @@ -12,6 +12,7 @@ #include "boost/tokenizer.hpp" #include "boost/lexical_cast.hpp" #include "boost/date_time/date_parsing.hpp" +#include "boost/date_time/special_values_parser.hpp" #include "boost/cstdint.hpp" #include <iostream> @@ -302,6 +303,25 @@ namespace date_time { { typedef typename time_type::time_duration_type time_duration; typedef typename time_type::date_type date_type; + typedef special_values_parser<date_type, std::string::value_type> svp_type; + + // given to_iso_string can produce a special value string + // then from_iso_string should be able to read a special value string + // the special_values_parser is expensive to set up and not thread-safe + // so it cannot be static, so we need to be careful about when we use it + if (svp_type::likely(s)) { + typedef typename svp_type::stringstream_type ss_type; + typedef typename svp_type::stream_itr_type itr_type; + typedef typename svp_type::match_results mr_type; + svp_type p; // expensive + mr_type mr; + ss_type ss(s); + itr_type itr(ss); + itr_type end; + if (p.match(itr, end, mr)) { + return time_type(static_cast<special_values>(mr.current_match)); + } + } //split date/time on a unique delimiter char such as ' ' or 'T' std::string date_string, tod_string; diff --git a/boost/date_time/time_resolution_traits.hpp b/boost/date_time/time_resolution_traits.hpp index 7ba42c20b5..b622488005 100644 --- a/boost/date_time/time_resolution_traits.hpp +++ b/boost/date_time/time_resolution_traits.hpp @@ -60,6 +60,29 @@ namespace date_time { static bool is_adapted() { return true;} }; + // + // Note about var_type, which is used to define the variable that + // stores hours, minutes, and seconds values: + // + // In Boost 1.65.1 and earlier var_type was boost::int32_t which suffers + // the year 2038 problem. Binary serialization of posix_time uses + // 32-bit values, and uses serialization version 0. + // + // In Boost 1.66.0 the var_type changed to std::time_t, however + // binary serialization was not properly versioned, so on platforms + // where std::time_t is 32-bits, it remains compatible, however on + // platforms where std::time_t is 64-bits, binary serialization ingest + // will be incompatible with previous versions. Furthermore, binary + // serialized output from 1.66.0 will not be compatible with future + // versions. Yes, it's a mess. Static assertions were not present + // in the serialization code to protect against this possibility. + // + // In Boost 1.67.0 the var_type was changed to boost::int64_t, + // ensuring the output size is 64 bits, and the serialization version + // was bumped. Static assertions were added as well, protecting + // future changes in this area. + // + template<typename frac_sec_type, time_resolutions res, #if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) @@ -68,7 +91,7 @@ namespace date_time { typename frac_sec_type::int_type resolution_adjust, #endif unsigned short frac_digits, - typename var_type = std::time_t > + typename var_type = boost::int64_t > // see note above class time_resolution_traits { public: typedef typename frac_sec_type::int_type fractional_seconds_type; diff --git a/boost/date_time/time_system_split.hpp b/boost/date_time/time_system_split.hpp index cf5931a4f2..8e1efbe4ca 100644 --- a/boost/date_time/time_system_split.hpp +++ b/boost/date_time/time_system_split.hpp @@ -11,6 +11,7 @@ #include <string> +#include <boost/config.hpp> #include "boost/date_time/compiler_config.hpp" #include "boost/date_time/special_defs.hpp" @@ -193,10 +194,15 @@ namespace date_time { const time_rep_type& rhs) { date_duration_type dd = lhs.day - rhs.day; - time_duration_type td(dd.days()*24,0,0); //days * 24 hours - time_duration_type td2 = lhs.time_of_day - rhs.time_of_day; - return td+td2; - // return time_rep_type(base.day-dd, base.time_of_day); + if (BOOST_LIKELY(!dd.is_special())) { + time_duration_type td(dd.days()*24,0,0); // days * 24 hours + time_duration_type td2 = lhs.time_of_day - rhs.time_of_day; + return td+td2; + } else { + time_duration_type td(dd.as_special()); + time_duration_type td2 = lhs.time_of_day - rhs.time_of_day; + return td+td2; + } } }; diff --git a/boost/date_time/tz_db_base.hpp b/boost/date_time/tz_db_base.hpp index 29d60063c3..5bf5b8af82 100644 --- a/boost/date_time/tz_db_base.hpp +++ b/boost/date_time/tz_db_base.hpp @@ -21,6 +21,7 @@ #include <boost/date_time/time_zone_names.hpp> #include <boost/date_time/time_zone_base.hpp> #include <boost/date_time/time_parsing.hpp> +#include <boost/algorithm/string.hpp> namespace boost { namespace date_time { @@ -170,8 +171,9 @@ namespace boost { /*! May throw bad_field_count exceptions */ void load_from_stream(std::istream &in) { - std::string buff; + std::string buff; while( std::getline(in, buff)) { + boost::trim_right(buff); parse_string(buff); } } |