
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? I'm using a time_input_facet with a formatting string of "%Y-%m-%d %H:%M:%S" imbued into a streams with exceptions(failbit) enabled. I'd like an exception raised when time parts such as 25:00:00 are parsed instead of getting the next day's date. I guess I could use regex validation, but was hoping to have support for this in the date_time library. Currently using cvs boost (RC_1_34_0). Thanks / Johan

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?
I'm using a time_input_facet with a formatting string of "%Y-%m-%d %H:%M:%S" imbued into a streams with exceptions(failbit) enabled. I'd like an exception raised when time parts such as 25:00:00 are parsed instead of getting the next day's date.
I guess I could use regex validation, but was hoping to have support for this in the date_time library.
Currently using cvs boost (RC_1_34_0).
Since these are treated as a time_duration for i/o there isn't a switch in the library to do this. I think the easiest way to do this would be to break down the streaming into it's parts and check in your client code. Here's the sketch if how it can be trivially done: 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); } Jeff

"Jeff Garland"
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]
Since these are treated as a time_duration for i/o there isn't a switch in the library to do this. I think the easiest way to do this would be to break down the streaming into it's parts and check in your client code. Here's the sketch if how it can be trivially done:
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); }
That's what I suspected. Thanks for the tip. // Johan

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]
Since these are treated as a time_duration for i/o there isn't a switch in the library to do this. I think the easiest way to do this would be to break down the streaming into it's parts and check in your client code. Here's the sketch if how it can be trivially done:
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. Regards, Johan

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]
Since these are treated as a time_duration for i/o there isn't a switch in the library to do this. I think the easiest way to do this would be to break down the streaming into it's parts and check in your client code. Here's the sketch if how it can be trivially done:
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
-- 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"))
{}
};
typedef CV::simple_exception_policy

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

"Johan Nilsson"
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;
Well, that was obviously a typo. Should be: time_duration td; istr >> td; tod = td; // might throw return istr; } / Johan

Johan Nilsson wrote:
Jeff Garland wrote:
Johan Nilsson wrote:
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>])"
I know...that's an enhancement that needs to go in, but it isn't there right now...
-- Code --
<snip details...>
[snip rest of example implementation]
The example looks fine, but support for fractional seconds would also be needed.
Yep, I was making a quick sketch not a complete implementation....
As for the streaming business, I believe that you're suggesting not to implement direct streaming support for time_of_day, e.g.:
I wasn't suggesting either way for the long run. I'm happy to include time_of_day and streaming if we think it's useful. However, it was in my mind that you could take the tod stuff and use it now instead of waiting around 6 months for a boost release... Jeff

Jeff Garland wrote:
Johan Nilsson wrote:
Jeff Garland wrote:
Johan Nilsson wrote:
[snip]
The example looks fine, but support for fractional seconds would also be needed.
Yep, I was making a quick sketch not a complete implementation....
As for the streaming business, I believe that you're suggesting not to implement direct streaming support for time_of_day, e.g.:
I wasn't suggesting either way for the long run. I'm happy to include time_of_day and streaming if we think it's useful. However, it was in my mind that you could take the tod stuff and use it now instead of waiting around 6 months for a boost release...
I've already implemented a workaround, but converting formatted clock times into ptimes with validation seems like a pretty common task to me. It's at least not the first time I've done something similar to that, and hopefully I'm not the only one ... +1 from my side for adding the functionality for e.g. release 1.35 Thanks for your help. // Johan
participants (2)
-
Jeff Garland
-
Johan Nilsson