boost::posix_time::time_duration greater than 24 hours

The following code snippet produces an ASSERT on my machine running WinXP (sp2) with VS8 (sp1) with boost v1.34.1: boost::posix_time::time_duration t(24, 0, 0); std::cout << t << std::end; The assertion occurs because there is a check in the underlying CRT that verifies the hours portion is between 0 and 23 inclusive. Is this something that might be fixed in boost 1.35?

Mark Van Dijk wrote:
The following code snippet produces an ASSERT on my machine running WinXP (sp2) with VS8 (sp1) with boost v1.34.1:
boost::posix_time::time_duration t(24, 0, 0); std::cout << t << std::end;
The assertion occurs because there is a check in the underlying CRT that verifies the hours portion is between 0 and 23 inclusive. Is this something that might be fixed in boost 1.35?
Well, I don't know what the problem is, but it isn't that the library restricts you to 24 hours. If you look in test/posix_time/testduration.cpp you'll see this test: time_duration tdl2(2000000, 0, 0, 0); check("2000000 hours", tdl2.hours() == 2000000); among others. And it clearly passes on VC8. So, I think you must have a compilation problem or something else going on. HTH, Jeff

On Dec 10, 2007 10:28 PM, Jeff Garland <jeff@crystalclearsoftware.com> wrote:
Mark Van Dijk wrote:
The following code snippet produces an ASSERT on my machine running WinXP (sp2) with VS8 (sp1) with boost v1.34.1:
boost::posix_time::time_duration t(24, 0, 0); std::cout << t << std::end;
The assertion occurs because there is a check in the underlying CRT that verifies the hours portion is between 0 and 23 inclusive. Is this something that might be fixed in boost 1.35?
Well, I don't know what the problem is, but it isn't that the library restricts you to 24 hours. If you look in test/posix_time/testduration.cpp you'll see this test:
time_duration tdl2(2000000, 0, 0, 0); check("2000000 hours", tdl2.hours() == 2000000);
among others. And it clearly passes on VC8. So, I think you must have a compilation problem or something else going on.
I can confirm that I have run into this issue as well. I can post a code snippet from my work computer tomorrow. My 'workaround' was to simply use 23 hours, 59 minutes, and 59 seconds, since we didn't require resolution greater than that, but it was definitely annoying. --Michael Fawcett

Michael Fawcett wrote:
On Dec 10, 2007 10:28 PM, Jeff Garland <jeff@crystalclearsoftware.com> wrote:
Mark Van Dijk wrote:
The following code snippet produces an ASSERT on my machine running WinXP (sp2) with VS8 (sp1) with boost v1.34.1:
boost::posix_time::time_duration t(24, 0, 0); std::cout << t << std::end;
The assertion occurs because there is a check in the underlying CRT that verifies the hours portion is between 0 and 23 inclusive. Is this something that might be fixed in boost 1.35? Well, I don't know what the problem is, but it isn't that the library restricts you to 24 hours. If you look in test/posix_time/testduration.cpp you'll see this test:
time_duration tdl2(2000000, 0, 0, 0); check("2000000 hours", tdl2.hours() == 2000000);
among others. And it clearly passes on VC8. So, I think you must have a compilation problem or something else going on.
I can confirm that I have run into this issue as well. I can post a code snippet from my work computer tomorrow.
My 'workaround' was to simply use 23 hours, 59 minutes, and 59 seconds, since we didn't require resolution greater than that, but it was definitely annoying.
So, why do the regression tests pass on all VC compilers....including the one above? Jeff

I On Dec 11, 2007 7:51 AM, Jeff Garland <jeff@crystalclearsoftware.com> wrote:
On Dec 10, 2007 10:28 PM, Jeff Garland <jeff@crystalclearsoftware.com> wrote:
Mark Van Dijk wrote:
The following code snippet produces an ASSERT on my machine running WinXP (sp2) with VS8 (sp1) with boost v1.34.1:
boost::posix_time::time_duration t(24, 0, 0); std::cout << t << std::end;
The assertion occurs because there is a check in the underlying CRT
Michael Fawcett wrote: that
verifies the hours portion is between 0 and 23 inclusive. Is this something that might be fixed in boost 1.35? Well, I don't know what the problem is, but it isn't that the library restricts you to 24 hours. If you look in test/posix_time/testduration.cpp you'll see this test:
time_duration tdl2(2000000, 0, 0, 0); check("2000000 hours", tdl2.hours() == 2000000);
among others. And it clearly passes on VC8. So, I think you must have a compilation problem or something else going on.
I can confirm that I have run into this issue as well. I can post a code snippet from my work computer tomorrow.
My 'workaround' was to simply use 23 hours, 59 minutes, and 59 seconds, since we didn't require resolution greater than that, but it was definitely annoying.
So, why do the regression tests pass on all VC compilers....including the one above?
I don't know why the tests pass but the problem started with vs 2005.
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

So, why do the regression tests pass on all VC compilers....including
Jeff Garland wrote: the one above?
the ASSERT() will only fire in debug mode - i assume that the regression tests are run in release mode?
It varies, but most of them are run in debug mode. Is there a stack trace or other information to help figure this out? Jeff

On Dec 11, 2007 4:47 PM, <jeff@crystalclearsoftware.com> wrote:
So, why do the regression tests pass on all VC compilers....including
Jeff Garland wrote: the one above?
the ASSERT() will only fire in debug mode - i assume that the regression tests are run in release mode?
It varies, but most of them are run in debug mode. Is there a stack trace or other information to help figure this out?
I'm trying to find the code (it was old, also it was using boost 1.33.1 so it may not be relevant) that displayed this problem. My simple attempts at recreating it are failing (in other words, boost::time_duration test(boost::posix_time::hours(24)) works just fine). --Michael Fawcett

The problem comes from the << operator it seems like they (MS) changed the file strftime.c to only deal with times with hours between 0 and 23. The reason that the tests do not catch the problem is because they do not test << ! Note the problem is in both debug and release modes it just is not caught in release mode. On Dec 11, 2007 3:47 PM, <jeff@crystalclearsoftware.com> wrote:
So, why do the regression tests pass on all VC compilers....including
Jeff Garland wrote: the one above?
the ASSERT() will only fire in debug mode - i assume that the regression tests are run in release mode?
It varies, but most of them are run in debug mode. Is there a stack trace or other information to help figure this out?
Jeff
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

My apologies for not specifing this earlier - i just assumed that many people had previously run into it. Michael Mathews is correct about the operator<<() and strftime.c being the cause of this issue. operator<<(ostream&, time_duration const&) basically converts the time_duration object to a tm struct using the function boost::posix_time::to_tm(time_duration const&). At this point, the tm structure contains an hours value of 24 - which Microsoft considers to be out-of-range. Further down the stack the _Strftime_l() function verifies the tm structure and everything comes to a crashing halt at this point. The MSDN docs for _Strftime_l() states that this function will check the tm struct for invalid and out-of-range values and will call the invalid parameter handler in this case. Hope that helps :-)

Mark Van Dijk wrote:
My apologies for not specifing this earlier - i just assumed that many people had previously run into it. Michael Mathews is correct about the operator<<() and strftime.c being the cause of this issue.
Thx for the detail. I don't normally develop on Windows -- unless I'm paid that is ;-)
operator<<(ostream&, time_duration const&) basically converts the time_duration object to a tm struct using the function boost::posix_time::to_tm(time_duration const&). At this point, the tm structure contains an hours value of 24 - which Microsoft considers to be out-of-range. Further down the stack the _Strftime_l() function verifies the tm structure and everything comes to a crashing halt at this point.
Yeah that clears up the mystery.
The MSDN docs for _Strftime_l() states that this function will check the tm struct for invalid and out-of-range values and will call the invalid parameter handler in this case.
Hope that helps :-)
While my initial reaction is that I'm not inclined to fix this problem since this seems like another case of an over-zealous 'safety cleanup' on MS part (The previous example was when MS disallowed tm from having negative years early in VC8 -- thus not correctly handling output for any date less than 1/1/1900 breaking working code - someone submitted a bug report and I believe they've changed it back now). Anyway, on my Linux machine with gcc4 things operate pretty much does what you might expect: time_duration td1(300,0,0); std::cout << td1 << std::endl; 300:00:00 That said, I am compelled by the open group spec for strftime saying that %H has a range of 00-23. So this seems like an ugly specification flaw in the date-time i/o concept for durations. Basically a really nasty problem for long time durations that depend on output of larger than 2 digit hours quantities. The quick hack would be to change time_facet.hpp to override the %H output. However, %H input is also broken because it only looks for 2 digits. So, I'm afraid this isn't a super quick issue to resolve... Note I'm guessing the reason this doesn't come up to much is that most people use time_duration output in the context of ptime which normalizes the day count on construction: date d(...); ptime t(d, hours(24)); //d+1 at 00:00::00 std::cout << t << std::endl; //fine...hours will be 0 Jeff
participants (6)
-
Jeff Garland
-
jeff@crystalclearsoftware.com
-
Mark Van Dijk
-
Michael Fawcett
-
Michael Mathews
-
Muck Jail