[date_time] How to create a date from string with specific format?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[date_time] How to create a date from string with specific format?

Christian Henning
Hi there, I would like to create a date object from a string with a
specific format ( mm-dd-yyyy ). How to I do that?

Thanks ahead,
Christian
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [date_time] How to create a date from string with specific format?

Dean Sturtevant

Good question -- this is the kind of thing I've been struggling with  
lately (I tried to post a question about it to the group, but I worded it  
poorly and the moderator rejected it). Anyway, here's the solution I came  
up with. I am sure there are better ones!

- Dean

     //! Utility function to split apart string. Returns # of components.
     inline
     int
     split_into_two_or_less(const std::string& s,
                            char sep,
                            std::string& first,
                            std::string& second)
     {
         int sep_pos = static_cast<int>(s.find(sep));
         if (sep_pos == -1) {
             first = s;
             return 1;
         }
         else {
             first = s.substr(0,sep_pos);
             second = s.substr(sep_pos+1);
             return 2;
         }
     }

     class expected_character : public boost::bad_lexical_cast
     {
         char _messagebuf[81];

       public:
         expected_character(const char* who, char ch, const char* str, int  
pos)
         {
             snprintf(_messagebuf, sizeof(_messagebuf),
                      "%s: Expected '%c' at position %d in \"%s\"",
                      who, ch, pos, str);
             _messagebuf[sizeof(_messagebuf)-1] = '\0';
         }

         const char* what() const throw()
         {
             return _messagebuf;
         }
     };

     //! Parse date string of form YYYY-MM-DD
     // Code adapted from boost/date_time/date_parsing.hpp's  
parse_undelimited_date()
     template <class date_type>
     inline
     date_type
     parse_delimited_iso_8601_date(const std::string& s)
     {
       int offsets[] = {4,1,2,1,2};
       int pos = 0;
       typedef typename date_type::year_type year_type;
       typename date_type::ymd_type ymd((year_type::min)(),1,1);
       // TODO: Is there a boost macro for sizeof(a)/sizeof(type)? or for  
the end of an array?
       boost::offset_separator osf(offsets,  
offsets+sizeof(offsets)/sizeof(offsets[0]));
       boost::tokenizer<boost::offset_separator> tok(s, osf);
       for(boost::tokenizer<boost::offset_separator>::iterator  
ti=tok.begin(); ti!=tok.end();++ti) {
         switch(pos) {
         case 0:
             ymd.year = boost::lexical_cast<unsigned short>(*ti); break;
         case 1:
             if (*ti != "-") {
                 throw expected_character("parse_delimited_iso_8601_date",  
'-', s.c_str(), 5);
             }
             break;
         case 2:
             ymd.month = boost::lexical_cast<unsigned short>(*ti); break;
         case 3:
             if (*ti != "-") {
                 throw expected_character("parse_delimited_iso_8601_date",  
'-', s.c_str(), 7);
             }
             break;
         case 4:
             ymd.day = boost::lexical_cast<unsigned short>(*ti); break;
         }
         pos++;
       }
       return date_type(ymd);
     }

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [date_time] How to create a date from string with specific format?

Christian Henning
Hi Dean, thanks for the answer.

Since, I know the format of the date strings I could also use
boost::regex for the general format and then feeding a date object
with the values. If I get an exception during the date object
contruction I know that the user provided me with garbage.

Here is some code:

   // date format: mm-dd-yyyy
   boost::regex oDateReg( "\\d{2}-\\d{2}-\\d{4}" );
   std::string strDate( "11-33-1997" );

   if( boost::regex_match( strDate
                         , oDateReg ))
   {
      try
      {
         std::string strMonth = strDate.substr( 0, 2 );
         std::string strDay   = strDate.substr( 3, 2 );
         std::string strYear  = strDate.substr( 6, 4 );

         unsigned int nYear  = boost::lexical_cast<unsigned int>(strYear);
         unsigned int nMonth = boost::lexical_cast<unsigned int>(strMonth);
         unsigned int nDay   = boost::lexical_cast<unsigned int>(strDay);

         date d( nYear, nMonth, nDay );

         date::ymd_type ymd = d.year_month_day();
      }
      catch( std::out_of_range oEx )
      {
         std::cout << "Error: " << oEx.what() << std::endl;
      }
   }

Any thoughts on that?

Thanks again,
Christian
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users