$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Jeff Garland (jeff_at_[hidden])
Date: 2006-09-26 11:06:08
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<unsigned short, 0, 23, bad_hour_of_day> 
hour_of_day_policies;
   typedef CV::constrained_value<hour_of_day_policies> 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<unsigned short, 0, 59, 
bad_minute_of_day> minute_of_day_policies;
   typedef CV::constrained_value<minute_of_day_policies> 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<unsigned short, 0, 59, 
bad_second_of_day> second_of_day_policies;
   typedef CV::constrained_value<second_of_day_policies> 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;
}