$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Johan Nilsson (r.johan.nilsson_at_[hidden])
Date: 2006-09-27 07:06:52
Jeff Garland wrote:
> Johan Nilsson wrote:
>> Jeff Garland wrote:
>>> Johan Nilsson wrote:
>>>> Hi,
>>>>
>>>> is there any way to force ptime stream input fail when the time
>>>> duration part is not between 00:00:00 and 23:59:59?
>>>>
>>
[snip]
>>>
>>> ptime getTime(istream& is)
>>> {
>>>    //assuming formatting is already set...
>>>    date d;
>>>    time_duration td;
>>>    is >> d;
>>>    is >> td;
>>>    if (td > hours(24)) {
>>>      throw ....
>>>    }
>>>    return ptime(d, td);
>>> }
>>
>> Hmmm, upon closer thought this will also pass for times such as
>> "22:99:00". I'd need to check all parts, which feels a bit
>> disturbing.
>>
>> I realize that a "time_duration" doesn't necessarily correspond to a
>> valid time of day. How about implementing something like
>> boost::posix_time::time_of_day, which would validate such things on
>> input? At least for me it's a bit unintuitive that it's possible to
>> sucessfully stream in a ptime when the time part isn't really a
>> valid clock time.
>
> Maybe something like this?
>
> -- Output --
>
> 23:59:59
> Hour out of range: 0 to 23
> Minute out of range: 0 to 59
> Second out of range: 0 to 59
Perhaps:
"<unit> out of range (valid: [<min>,<max>])"
would be more descriptive, or even something like:
"<unit> out of range (is: <actual>, valid: [<min>, <max>])"
>
> -- Code --
>
> //tod_test.cpp
> #include "boost/date_time/posix_time/posix_time.hpp"
> #include <iostream>
>
> //In response to question from Johan Nilsson
>
>
> namespace boost {
> namespace posix_time {
>
>   struct bad_hour_of_day : public std::out_of_range
>   {
>     bad_hour_of_day() :
>       std::out_of_range(std::string("Hour out of range: 0 to 23"))
>     {}
>   };
[snip rest of example implementation]
The example looks fine, but support for fractional seconds would also be 
needed.
As for the streaming business, I believe that you're suggesting not to 
implement direct streaming support for time_of_day, e.g.:
---
using namespace boost::posix_time;
time_of_day tod(12, 23, 34, millis(908)), tod2;
std::stringstream str;
// imbue ...
str << tod;
str >> tod2;
assert(tod == tod2);
---
Rather, something like:
----
using namespace boost::posix_time;
time_of_day tod(12, 23, 34, millis(908));
std::stringstream str;
// imbue ...
str << tod.to_time_duration();
time_duration td;
str >> td;
time_of_day tod2(td); // could throw!!
assert(tod == tod2);
----
I find the latter a bit verbose to use, but I guess simple wrappers could be 
added:
----
template<...>
std::basic_istream<...>& operator>>(std::basic_istream<...>& istr, 
time_of_day& tod)
{
    time_duration td;
    istr >> tod;
    return istr;
}
template<...>
std::basic_ostream<...>& operator<<(std::basic_ostream<...>& istr, 
time_of_day& tod)
{
    ostr << tod.to_time_duration();
    return ostr;
}
---
Thanks / Johan