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
hour_of_day_policies;
typedef CV::constrained_value hour_of_day_rep;
class hour_of_day : public hour_of_day_rep {
public:
hour_of_day(unsigned short hour) : hour_of_day_rep(hour) {}
operator unsigned short() const {return value_;}
private:
};
struct bad_minute_of_day : public std::out_of_range
{
bad_minute_of_day() :
std::out_of_range(std::string("Minute out of range: 0 to 59"))
{}
};
typedef CV::simple_exception_policy minute_of_day_policies;
typedef CV::constrained_value minute_of_day_rep;
class minute_of_day : public minute_of_day_rep {
public:
minute_of_day(unsigned short m) : minute_of_day_rep(m) {}
operator unsigned short() const {return value_;}
private:
};
struct bad_second_of_day : public std::out_of_range
{
bad_second_of_day() :
std::out_of_range(std::string("Second out of range: 0 to 59"))
{}
};
typedef CV::simple_exception_policy second_of_day_policies;
typedef CV::constrained_value second_of_day_rep;
class second_of_day : public second_of_day_rep {
public:
second_of_day(unsigned short s) : second_of_day_rep(s) {}
operator unsigned short() const {return value_;}
private:
};
class time_of_day {
public:
time_of_day(hour_of_day h, minute_of_day m, second_of_day s) :
h_(h), m_(m), s_(s)
{}
time_duration to_duration() const
{
return time_duration(h_, m_, s_);
}
private:
hour_of_day h_;
minute_of_day m_;
second_of_day s_;
};
}}
int main()
{
using namespace boost::posix_time;
time_of_day tod(23,59,59);
std::cout << tod.to_duration() << std::endl;
try {
time_of_day tod1(24,0,0);
}
catch(std::out_of_range& e) {
std::cout << e.what() << std::endl;
}
try {
time_of_day tod2(0,60,0);
}
catch(std::out_of_range& e) {
std::cout << e.what() << std::endl;
}
try {
time_of_day tod3(0,0,60);
}
catch(std::out_of_range& e) {
std::cout << e.what() << std::endl;
}
return 0;
}