Boost logo

Boost Users :

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

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net