...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::date_time::format_date_parser — Class with generic date parsing using a format string.
// In header: <boost/date_time/format_date_parser.hpp> template<typename date_type, typename charT> class format_date_parser { public: // types typedef std::basic_string< charT > string_type; typedef std::basic_istringstream< charT > stringstream_type; typedef std::istreambuf_iterator< charT > stream_itr_type; typedef string_type::const_iterator const_itr; typedef date_type::year_type year_type; typedef date_type::month_type month_type; typedef date_type::day_type day_type; typedef date_type::duration_type duration_type; typedef date_type::day_of_week_type day_of_week_type; typedef date_type::day_of_year_type day_of_year_type; typedef string_parse_tree< charT > parse_tree_type; typedef parse_tree_type::parse_match_result_type match_results; typedef std::vector< std::basic_string< charT > > input_collection_type; // construct/copy/destruct format_date_parser(const string_type &, const input_collection_type &, const input_collection_type &, const input_collection_type &, const input_collection_type &); format_date_parser(const string_type &, const std::locale &); format_date_parser(const format_date_parser< date_type, charT > &); // public member functions string_type format() const; void format(string_type); void short_month_names(const input_collection_type &); void long_month_names(const input_collection_type &); void short_weekday_names(const input_collection_type &); void long_weekday_names(const input_collection_type &); date_type parse_date(const string_type &, const string_type &, const special_values_parser< date_type, charT > &) const; date_type parse_date(std::istreambuf_iterator< charT > &, std::istreambuf_iterator< charT > &, const special_values_parser< date_type, charT > &) const; date_type parse_date(std::istreambuf_iterator< charT > &, std::istreambuf_iterator< charT > &, string_type, const special_values_parser< date_type, charT > &) const; month_type parse_month(std::istreambuf_iterator< charT > &, std::istreambuf_iterator< charT > &, string_type) const; month_type parse_month(std::istreambuf_iterator< charT > &, std::istreambuf_iterator< charT > &, string_type, match_results &) const; day_type parse_var_day_of_month(std::istreambuf_iterator< charT > &, std::istreambuf_iterator< charT > &) const; day_type parse_day_of_month(std::istreambuf_iterator< charT > &, std::istreambuf_iterator< charT > &) const; day_of_week_type parse_weekday(std::istreambuf_iterator< charT > &, std::istreambuf_iterator< charT > &, string_type) const; day_of_week_type parse_weekday(std::istreambuf_iterator< charT > &, std::istreambuf_iterator< charT > &, string_type, match_results &) const; year_type parse_year(std::istreambuf_iterator< charT > &, std::istreambuf_iterator< charT > &, string_type) const; year_type parse_year(std::istreambuf_iterator< charT > &, std::istreambuf_iterator< charT > &, string_type, match_results &) const; };
The following is the set of recognized format specifiers
a - Short weekday name
A - Long weekday name
b - Abbreviated month name
B - Full month name
d - Day of the month as decimal 01 to 31
j - Day of year as decimal from 001 to 366
m - Month name as a decimal 01 to 12
U - Week number 00 to 53 with first Sunday as the first day of week 1?
w - Weekday as decimal number 0 to 6 where Sunday == 0
W - Week number 00 to 53 where Monday is first day of week 1
x - facet default date representation
y - Year without the century - eg: 04 for 2004
Y - Year with century
The weekday specifiers (a and A) do not add to the date construction, but they provide a way to skip over the weekday names for formats that provide them.
todo -- Another interesting feature that this approach could provide is an option to fill in any missing fields with the current values from the clock. So if you have m-d the parser would detect the missing year value and fill it in using the clock.
todo -- What to do with the x. x in the classic facet is just bad...
format_date_parser
public
construct/copy/destructformat_date_parser(const string_type & format_str, const input_collection_type & month_short_names, const input_collection_type & month_long_names, const input_collection_type & weekday_short_names, const input_collection_type & weekday_long_names);
format_date_parser(const string_type & format_str, const std::locale & locale);
format_date_parser(const format_date_parser< date_type, charT > & fdp);
format_date_parser
public member functionsstring_type format() const;
void format(string_type format_str);
void short_month_names(const input_collection_type & month_names);
void long_month_names(const input_collection_type & month_names);
void short_weekday_names(const input_collection_type & weekday_names);
void long_weekday_names(const input_collection_type & weekday_names);
date_type parse_date(const string_type & value, const string_type & format_str, const special_values_parser< date_type, charT > & sv_parser) const;
date_type parse_date(std::istreambuf_iterator< charT > & sitr, std::istreambuf_iterator< charT > & stream_end, const special_values_parser< date_type, charT > & sv_parser) const;
date_type parse_date(std::istreambuf_iterator< charT > & sitr, std::istreambuf_iterator< charT > & stream_end, string_type format_str, const special_values_parser< date_type, charT > & sv_parser) const;
Of all the objects that the format_date_parser
can parse, only a date can be a special value. Therefore, only parse_date checks for special_values.
month_type parse_month(std::istreambuf_iterator< charT > & sitr, std::istreambuf_iterator< charT > & stream_end, string_type format_str) const;Throws bad_month if unable to parse.
month_type parse_month(std::istreambuf_iterator< charT > & sitr, std::istreambuf_iterator< charT > & stream_end, string_type format_str, match_results & mr) const;Throws bad_month if unable to parse.
day_type parse_var_day_of_month(std::istreambuf_iterator< charT > & sitr, std::istreambuf_iterator< charT > & stream_end) const;Expects 1 or 2 digits 1-31. Throws bad_day_of_month if unable to parse.
day_type parse_day_of_month(std::istreambuf_iterator< charT > & sitr, std::istreambuf_iterator< charT > & stream_end) const;Expects 2 digits 01-31. Throws bad_day_of_month if unable to parse.
day_of_week_type parse_weekday(std::istreambuf_iterator< charT > & sitr, std::istreambuf_iterator< charT > & stream_end, string_type format_str) const;
day_of_week_type parse_weekday(std::istreambuf_iterator< charT > & sitr, std::istreambuf_iterator< charT > & stream_end, string_type format_str, match_results & mr) const;
year_type parse_year(std::istreambuf_iterator< charT > & sitr, std::istreambuf_iterator< charT > & stream_end, string_type format_str) const;throws bad_year if unable to parse
year_type parse_year(std::istreambuf_iterator< charT > & sitr, std::istreambuf_iterator< charT > & stream_end, string_type format_str, match_results & mr) const;throws bad_year if unable to parse