From: Jeff Garland (jeff_at_[hidden])
Date: 2003-08-05 09:14:29
On Mon, 4 Aug 2003 20:17:03 -0700, Stephan T. Lavavej wrote
> time_duration behaves highly nonintuitively. A time_duration should
> be convertible to seconds by calculating td.hours() * 3600 +
> td.minutes() * 60 + td.seconds(), right? Wrong!
Hmm, I agree that this is not nice...
> In short, the .minutes() and .seconds() of a negative time_duration should
> be negative, but are not. Since the negative sign is attached to the
> hours only, the complicated above seconds_from_time_duration()
> function must be used in order to avoid incorrectly converting
> time_durations to seconds.
> I believe that there are two solutions to this bug:
> 1. Make all of time_duration's quantities unsigned and store whether
> the time_duration is negative in a boolean. This cleanly separates
> storing the direction of the time_duration from the magnitude.
> However, this is undesirable because converting a time_duration to
> seconds would still require (td.is_negative() ? -1 : 1) * (td.hours()
> * 3600 + td.minutes() * 60 + td.seconds()). If the user forget the
> parentheses around the second expression, then again the result
> would be correct except when the negative time_duration has nonzero
> seconds or minutes.
Plus it makes the memory footprint of time duration bigger which is not
desirable. Of course this same solution could be implemented by only
returning the abs in the hours() so that it is consistent with the
other methods and provides only the magnitude.
> 2. If a negative time_duration is produced, all of its fields should
> be negative or zero. This has the advantage of allowing easy
> conversion to seconds: td.hours() * 3600 + td.minutes() * 60 +
> td.seconds(), which is what a user will naturally want to write.
> Users may construct time_durations with differently signed fields,
> but these will have well-defined meanings (just as 1 hour 1 minute
> 61 seconds is equal to 1 hour 2 minutes 1 second, 1 hour 0 minutes
> -1 seconds is equal to 0 hours 59 minutes 59 seconds).
> I believe that (2) is the correct solution and has no downsides.
The downside of this is that when you are printing a time duration:
std::cout << td.hours() << ':' << td.minutes() << ':' << td.seconds();
you have to take remove the sign from the minutes and seconds.
I have a third suggestion:
- Implement (1) using abs() in the hours() method
- Add a total_seconds function to the library so you don't have to write it.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk