date_type parse_undelimited_date(const std::string& s) { int offsets[] = {4,2,2}; int pos = 0; typedef typename date_type::year_type year_type; //typename date_type::ymd_type ymd((year_type::min)(),1,1); unsigned short y = 0, m = 0, d = 0; /* The two bool arguments state that parsing will not wrap * (only the first 8 characters will be parsed) and partial * strings will not be parsed. * Ex: * "2005121" will parse 2005 & 12, but not the "1" */ boost::offset_separator osf(offsets, offsets+3, false, false); typedef typename boost::tokenizer<boost::offset_separator, std::basic_string<char>::const_iterator, std::basic_string<char> > tokenizer_type; tokenizer_type tok(s, osf); for(typename tokenizer_type::iterator ti=tok.begin(); ti!=tok.end();++ti) { unsigned short i = boost::lexical_cast<unsigned short>(*ti); switch(pos) { case 0: y = i; break; case 1: m = i; break; case 2: d = i; break; default: break; } pos++; } return date_type(y,m,d); }
/*! Will throw an 'invalid_argument' exception if a partial_date object, * instantiated with Feb-29, has get_date called with a non-leap year. * Example: * @code * partial_date pd(29, Feb); * pd.get_date(2003); // throws invalid_argument exception * pg.get_date(2000); // returns 2000-2-29 * @endcode */ date_type get_date(year_type y) const { if((day_ == 29) && (month_ == 2) && !(calendar_type::is_leap_year(y))) { std::ostringstream ss; ss << "No Feb 29th in given year of " << y << "."; boost::throw_exception(std::invalid_argument(ss.str())); } return date_type(y, month_, day_); }
/*! Will throw an 'invalid_argument' exception if a partial_date object, * instantiated with Feb-29, has get_date called with a non-leap year. * Example: * @code * partial_date pd(29, Feb); * pd.get_date(2003); // throws invalid_argument exception * pg.get_date(2000); // returns 2000-2-29 * @endcode */ date_type get_date(year_type y) const { if((day_ == 29) && (month_ == 2) && !(calendar_type::is_leap_year(y))) { std::stringstream ss(""); ss << "No Feb 29th in given year of " << y << "."; throw std::invalid_argument(ss.str()); //return date_type(1,1,1); // should never reach } else { return date_type(y, month_, day_); } }
date_type parse_date(const std::string& s, int order_spec = ymd_order_iso) { std::string spec_str; if(order_spec == ymd_order_iso) { spec_str = "ymd"; } else if(order_spec == ymd_order_dmy) { spec_str = "dmy"; } else { // (order_spec == ymd_order_us) spec_str = "mdy"; } typedef typename date_type::year_type year_type; typedef typename date_type::month_type month_type; unsigned pos = 0; unsigned short year(0), month(0), day(0); typedef typename std::basic_string<char>::traits_type traits_type; typedef boost::char_separator<char, traits_type> char_separator_type; typedef boost::tokenizer<char_separator_type, std::basic_string<char>::const_iterator, std::basic_string<char> > tokenizer; typedef boost::tokenizer<char_separator_type, std::basic_string<char>::const_iterator, std::basic_string<char> >::iterator tokenizer_iterator; // may need more delimiters, these work for the regression tests const char sep_char[] = {',','-','.',' ','/','\0'}; char_separator_type sep(sep_char); tokenizer tok(s,sep); for(tokenizer_iterator beg=tok.begin(); beg!=tok.end() && pos < spec_str.size(); ++beg, ++pos) { switch(spec_str.at(pos)) { case 'y': { year = boost::lexical_cast<unsigned short>(*beg); break; } case 'm': { month = month_str_to_ushort<month_type>(*beg); break; } case 'd': { day = boost::lexical_cast<unsigned short>(*beg); break; } default: break; } //switch } return date_type(year, month, day); }
date_type parse_date(const std::string& s) { typedef typename date_type::year_type year_type; int pos = 0; typename date_type::ymd_type ymd(year_type::min(),1,1); boost::tokenizer<boost::char_delimiters_separator<char> > tok(s); for(boost::tokenizer<>::iterator beg=tok.begin(); beg!=tok.end();++beg){ int i = boost::lexical_cast<int>(*beg); switch(pos) { case 0: ymd.year = i; break; case 1: ymd.month = i; break; case 2: ymd.day = i; break; }; pos++; } return date_type(ymd); }
date_type parse_date(const std::string& s, int order_spec = ymd_order_iso) { std::string spec_str(""); if(order_spec == ymd_order_iso) { spec_str = "ymd"; } else if(order_spec == ymd_order_dmy) { spec_str = "dmy"; } else { // (order_spec == ymd_order_us) spec_str = "mdy"; } typedef typename date_type::year_type year_type; typedef typename date_type::month_type month_type; unsigned pos = 0; typename date_type::ymd_type ymd(year_type::min(),1,1); boost::tokenizer<boost::char_delimiters_separator<char> > tok(s); for(boost::tokenizer<>::iterator beg=tok.begin(); beg!=tok.end(), pos < spec_str.size(); ++beg, ++pos) { unsigned short i =0; switch(spec_str.at(pos)) { case 'y': { i = boost::lexical_cast<unsigned short>(*beg); ymd.year = i; break; } case 'm': { ymd.month = month_str_to_ushort<month_type>(*beg); break; } case 'd': { i = boost::lexical_cast<unsigned short>(*beg); ymd.day = i; break; } } //switch } return date_type(ymd); }
date_type parse_undelimited_date(const std::string& s) { int offsets[] = {4,2,2}; int pos = 0; typedef typename date_type::year_type year_type; typename date_type::ymd_type ymd(year_type::min(),1,1); boost::offset_separator osf(offsets, offsets+3); boost::tokenizer<boost::offset_separator> tok(s, osf); for(boost::tokenizer<boost::offset_separator>::iterator ti=tok.begin(); ti!=tok.end();++ti) { unsigned short i = boost::lexical_cast<unsigned short>(*ti); // std::cout << i << std::endl; switch(pos) { case 0: ymd.year = i; break; case 1: ymd.month = i; break; case 2: ymd.day = i; break; } pos++; } return date_type(ymd); }
//! Get the UTC day as a date type static date_type universal_day() { return date_type(universal_day_ymd()); }
//! Get the local day as a date type static date_type local_day() { return date_type(local_day_ymd()); }
date_type parse_date(std::istreambuf_iterator<charT>& sitr, std::istreambuf_iterator<charT>& stream_end, string_type format) const { bool use_current_char = false; charT current_char = *sitr; unsigned short year(0), month(0), day(0), day_of_year(0); const_itr itr(format.begin()); while (itr != format.end() && (sitr != stream_end)) { if (*itr == '%') { itr++; if (*itr != '%') { //ignore '%%' unsigned short i = 0; switch(*itr) { case 'a': { //this value is just throw away. It could be used for //error checking potentially, but it isn't helpful in //actually constructing the date - we just need to get it //out of the stream match_results mr = m_weekday_short_names.match(sitr, stream_end); unsigned int wkday = mr.current_match; if (mr.has_remaining()) { current_char = mr.last_char(); use_current_char = true; } break; } case 'A': { //this value is just throw away. It could be used for //error checking potentially, but it isn't helpful in //actually constructing the date - we just need to get it //out of the stream match_results mr = m_weekday_long_names.match(sitr, stream_end); unsigned int wkday = mr.current_match; if (mr.has_remaining()) { current_char = mr.last_char(); use_current_char = true; } break; } case 'b': { match_results mr = m_month_short_names.match(sitr, stream_end); month = mr.current_match; if (mr.has_remaining()) { current_char = mr.last_char(); use_current_char = true; } break; } case 'B': { match_results mr = m_month_long_names.match(sitr, stream_end); month = mr.current_match; if (mr.has_remaining()) { current_char = mr.last_char(); use_current_char = true; } break; } case 'd': { day = var_string_to_int<unsigned short, charT>(sitr, 2); break; } case 'j': { day_of_year = fixed_string_to_int<unsigned short, charT>(sitr, 3); break; } case 'm': { month = var_string_to_int<unsigned short, charT>(sitr, 2); break; } case 'Y': { year = fixed_string_to_int<unsigned short, charT>(sitr, 4); break; } case 'y': { year = fixed_string_to_int<unsigned short, charT>(sitr, 2); year += 2000; //make 2 digit years in this century break; } default: {} //ignore those we don't understand }//switch } itr++; //advance past format specifier } else { //skip past chars in format and in buffer itr++; if (use_current_char) { use_current_char = false; current_char = *sitr; } else { sitr++; } } } if (day_of_year != 0) { date_type d(year-1,12,31); //end of prior year return d + duration_type(day_of_year); } return date_type(year, month, day); }