
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