Index: boost/date_time/time_facet.hpp =================================================================== --- boost/date_time/time_facet.hpp (revision 51616) +++ boost/date_time/time_facet.hpp (working copy) @@ -159,7 +159,7 @@ template const typename time_formats::char_type time_formats::default_time_duration_format[11] = - {'%','H',':','%','M',':','%','S','%','F'}; + {'%','O',':','%','M',':','%','S','%','F'}; Index: boost/date_time/format_date_parser.hpp =================================================================== --- boost/date_time/format_date_parser.hpp (revision 51616) +++ boost/date_time/format_date_parser.hpp (working copy) @@ -100,13 +100,13 @@ inline int_type var_string_to_int(std::istreambuf_iterator& itr, - std::istreambuf_iterator& /* stream_end */, + const std::istreambuf_iterator& stream_end, unsigned int max_length) { typedef std::basic_string string_type; unsigned int j = 0; string_type s; - while ((j < max_length) && std::isdigit(*itr)) { + while (itr != stream_end && (j < max_length) && std::isdigit(*itr)) { s += (*itr); itr++; j++; Index: libs/date_time/test/posix_time/testtime_facet.cpp =================================================================== --- libs/date_time/test/posix_time/testtime_facet.cpp (revision 51616) +++ libs/date_time/test/posix_time/testtime_facet.cpp (working copy) @@ -197,6 +197,16 @@ ss.str(""); } + // "Long" time durations (longer then 24 hours) checks + { + std::string result; + std::stringstream ss; + time_duration td9(101, 23, 34); + ss << td9; + result = "101:23:34"; + check("Long time_duration", result == ss.str()); + } + // The test verifies that #2698 is fixed. That is, the time and date facet should // not dereference end() iterator for the format string in do_put_tm. { Index: libs/date_time/test/posix_time/testtime_serialize.cpp =================================================================== --- libs/date_time/test/posix_time/testtime_serialize.cpp (revision 51616) +++ libs/date_time/test/posix_time/testtime_serialize.cpp (working copy) @@ -32,6 +32,7 @@ #else time_duration td(12,13,52,123456); #endif + time_duration td_l(101, 23, 45); ptime pt(d, td); time_period tp(pt, ptime(date(2002, Oct, 31), hours(19))); ptime sv_pt1(not_a_date_time); @@ -41,6 +42,7 @@ // for loading in from archive date d2(not_a_date_time); time_duration td2(1,0,0); + time_duration td2_l(1, 0, 0); ptime pt2(d2, td2); time_period tp2(pt2, hours(1)); ptime sv_pt3(min_date_time); @@ -66,6 +68,7 @@ save_to(oa, BOOST_SERIALIZATION_NVP(sv_pt2)); save_to(oa, BOOST_SERIALIZATION_NVP(tp)); save_to(oa, BOOST_SERIALIZATION_NVP(td)); + save_to(oa, BOOST_SERIALIZATION_NVP(td_l)); save_to(oa, BOOST_SERIALIZATION_NVP(sv_td)); #else save_to(oa, pt); @@ -73,6 +76,7 @@ save_to(oa, sv_pt2); save_to(oa, tp); save_to(oa, td); + save_to(oa, td_l); save_to(oa, sv_td); #endif // DATE_TIME_XML_SERIALIZE }catch(archive::archive_exception& ae){ @@ -95,6 +99,7 @@ ia >> BOOST_SERIALIZATION_NVP(sv_pt4); ia >> BOOST_SERIALIZATION_NVP(tp2); ia >> BOOST_SERIALIZATION_NVP(td2); + ia >> BOOST_SERIALIZATION_NVP(td2_l); ia >> BOOST_SERIALIZATION_NVP(sv_td2); #else ia >> pt2; @@ -102,6 +107,7 @@ ia >> sv_pt4; ia >> tp2; ia >> td2; + ia >> td2_l; ia >> sv_td2; #endif // DATE_TIME_XML_SERIALIZE }catch(archive::archive_exception& ae){ @@ -115,6 +121,7 @@ check("special_values ptime (pos_infin)", sv_pt2 == sv_pt4); check("time_period", tp == tp2); check("time_duration", td == td2); + check("time_duration long", td_l == td2_l); check("special_values time_duration (neg_infin)", sv_td == sv_td2); return printTestStats(); Index: libs/date_time/test/posix_time/testtime_input_facet.cpp =================================================================== --- libs/date_time/test/posix_time/testtime_input_facet.cpp (revision 51616) +++ libs/date_time/test/posix_time/testtime_input_facet.cpp (working copy) @@ -104,6 +104,7 @@ #endif // test all flags that appear in time_input_facet + iss.clear(); iss.str("12:34:56 2005-Jan-15 12:34:56"); iss >> td; iss >> pt; @@ -111,34 +112,52 @@ // the following test insures %F parsing stops at the appropriate point check("Default format ptime", pt == ptime(date(2005,01,15),time_duration(12,34,56))); + iss.clear(); iss.str("14:13:12 extra stuff"); // using default %H:%M:%S%F format iss >> td; check("Default frac_sec format time_duration", td == time_duration(14,13,12)); + + iss.clear(); + iss.str("100:11:22"); // default format should work for more than 24 hours + iss >> td; + check("Default format time_duration longer then 24 hours", + td == time_duration(100, 11, 22)); time_input_facet* facet = new time_input_facet(); std::locale loc(std::locale::classic(), facet); facet->time_duration_format("%H:%M:%S%f"); iss.imbue(loc); + iss.clear(); iss.str("14:13:12.0 extra stuff"); iss >> td; check("Required-frac_sec format time_duration", td == time_duration(14,13,12)); + iss.clear(); iss.str("12"); facet->time_duration_format("%H"); iss >> td; check("Hours format", td == hours(12)); + iss.clear(); + iss.str("101"); + facet->time_duration_format("%O"); + iss >> td; + check("Hours format long", td == hours(101)); + + iss.clear(); iss.str("05"); facet->time_duration_format("%M"); iss >> td; check("Minutes format", td == minutes(5)); + iss.clear(); iss.str("45"); facet->time_duration_format("%S"); iss >> td; check("Seconds w/o frac_sec format", td == seconds(45)); + iss.clear(); iss.str("10.01"); facet->time_duration_format("%s"); iss >> td; @@ -148,30 +167,36 @@ check("Seconds w/ frac_sec format", td == time_duration(0,0,10,10000)); #endif + iss.clear(); iss.str("2005-105T23:59"); facet->format("%Y-%jT%H:%M"); // extended ordinal format iss >> pt; check("Extended Ordinal format", pt == ptime(date(2005,4,15),time_duration(23,59,0))); /* this is not implemented yet. The flags: %I & %p are not parsed + iss.clear(); iss.str("2005-Jun-14 03:15:00 PM"); facet->format("%Y-%b-%d %I:%M:%S %p"); iss >> pt; check("12 hour time format (AM/PM)", pt == ptime(date(2005,6,14),time_duration(15,15,0))); */ + iss.clear(); iss.str("2005-Jun-14 15:15:00 %d"); facet->format("%Y-%b-%d %H:%M:%S %%d"); iss >> pt; check("Literal '%' in format", pt == ptime(date(2005,6,14),time_duration(15,15,0))); + iss.clear(); iss.str("15:15:00 %d"); facet->time_duration_format("%H:%M:%S %%d"); iss >> td; check("Literal '%' in time_duration format", td == time_duration(15,15,0)); + iss.clear(); iss.str("2005-Jun-14 15:15:00 %14"); facet->format("%Y-%b-%d %H:%M:%S %%%d"); // %% => % & %d => day_of_month iss >> pt; check("Multiple literal '%'s in format", pt == ptime(date(2005,6,14),time_duration(15,15,0))); + iss.clear(); iss.str("15:15:00 %15"); facet->time_duration_format("%H:%M:%S %%%M"); iss >> td; @@ -281,6 +306,7 @@ // special_values tests. prove the individual flags catch special_values // NOTE: these flags all by themselves will not parse a complete ptime, // these are *specific* special_values tests + iss.clear(); iss.str("+infinity -infinity"); facet->format("%H"); facet->time_duration_format("%H"); @@ -289,6 +315,7 @@ check("Special value: ptime %H flag", pt == ptime(pos_infin)); check("Special value: time_duration %H flag", td == time_duration(neg_infin)); + iss.clear(); iss.str("not-a-date-time +infinity"); facet->format("%M"); facet->time_duration_format("%M"); @@ -297,6 +324,7 @@ check("Special value: ptime %M flag", pt == ptime(not_a_date_time)); check("Special value: time_duration %M flag", td == time_duration(pos_infin)); + iss.clear(); iss.str("-infinity not-a-date-time "); facet->format("%S"); facet->time_duration_format("%S"); @@ -305,6 +333,7 @@ check("Special value: ptime %S flag", pt == ptime(neg_infin)); check("Special value: time_duration %S flag", td == time_duration(not_a_date_time)); + iss.clear(); iss.str("+infinity -infinity"); facet->format("%s"); facet->time_duration_format("%s"); @@ -313,6 +342,7 @@ check("Special value: ptime %s flag", pt == ptime(pos_infin)); check("Special value: time_duration %s flag", td == time_duration(neg_infin)); + iss.clear(); iss.str("not-a-date-time +infinity"); facet->format("%j"); facet->time_duration_format("%f"); @@ -323,6 +353,7 @@ // time_period tests - the time_period_parser is thoroughly tested in gregorian tests // default period format is closed range so last ptime is included in peiod + iss.clear(); iss.str("[2005-Jan-01 00:00:00/2005-Dec-31 23:59:59]"); facet->format(time_input_facet::default_time_input_format); // reset format iss >> tp; Index: libs/date_time/test/posix_time/testparse_time.cpp =================================================================== --- libs/date_time/test/posix_time/testparse_time.cpp (revision 51616) +++ libs/date_time/test/posix_time/testparse_time.cpp (working copy) @@ -102,6 +102,11 @@ } #endif + std::string s9b("100:00:00"); // duration may span more than 24 hours + time_duration td9= boost::date_time::parse_delimited_time_duration(s9b); + check("parse long time duration: " + s9b, + td9 == time_duration(100, 0, 0)); + #ifdef BOOST_DATE_TIME_HAS_NANOSECONDS std::string ts2("2002-12-31 00:00:00.999999999"); Index: libs/date_time/xmldoc/time_facet.xml =================================================================== --- libs/date_time/xmldoc/time_facet.xml (revision 51616) +++ libs/date_time/xmldoc/time_facet.xml (working copy) @@ -72,7 +72,7 @@ Sets the time_duration format. The time_duration format has the ability to display the sign of the duration. The '%+' flag will always display the sign. The '%-' will only display if the sign is negative. Currently the '-' and '+' characters are used to denote the sign. - f->time_duration_format("%+%H:%M"); + f->time_duration_format("%+%O:%M"); // hours and minutes only w/ sign always displayed time_duration td1(3, 15, 56); time_duration td2(-12, 25, 32); Index: libs/date_time/xmldoc/format_flags.xml =================================================================== --- libs/date_time/xmldoc/format_flags.xml (revision 51616) +++ libs/date_time/xmldoc/format_flags.xml (working copy) @@ -301,7 +301,7 @@ - %O + %O * The number of hours in a time duration as a decimal number (range 0 to max. representable duration); single digits are preceded by a zero. @@ -309,6 +309,16 @@ + %H + The number of hours in a time duration as a decimal number (range 0 to 23); single digits + are preceded by a zero. Using this flag with a value that is out of range is an undefined + behavior. Probably an assertion in a debug version. + + + + + + %I ! The hour as a decimal number using a 12-hour clock @@ -481,7 +491,7 @@ - %-%H:%M:%S%F ! + %-%O:%M:%S%F ! Default time_duration format for output. Sign will only be displayed for negative durations. @@ -489,7 +499,7 @@ - %H:%M:%S%F + %O:%M:%S%F Default time_duration format for input.