Boost logo

Boost :

From: Jeff Garland (jeff_at_[hidden])
Date: 2007-12-11 22:34:57

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


Boost list run by bdawes at, gregod at, cpdaniel at, john at