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!
This is the correct way to do it: int seconds_from_time_duration(const boost::posix_time::time_duration& td) { const time_duration positive = td.is_negative() ? td.invert_sign() : td; return (td.is_negative() ? -1 : 1) * (positive.hours() * 3600 + positive.minutes() * 60 + positive.seconds() ); } I developed this function after being bitten by time_duration's nonintuitive behavior. This entertaining story goes as follows: On 2:56:15 July 21, 1969 (UTC), Neil Armstrong first set foot on the Moon. On 0:00:00 January 1, 1970 (UTC), the Unix epoch began. When represented as Boost times, Armstrong - Unix is a negative time_duration. I printed out the hours, minutes, and seconds fields of this time_duration and got: Hours: -3933 Minutes: 3 Seconds: 45 Adding -3933 hours to Unix gives 3:00:00 July 21, 1969. -3 minutes and -45 seconds must then be added to produce Armstrong time. But the time_duration specifies that 3 minutes and 45 seconds should be added. Ooops. 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. 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. Stephan T. Lavavej http://stl.caltech.edu _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost