Added a date_traits_t type

This commit is contained in:
John Wiegley 2009-11-17 22:03:32 -05:00
parent c28d828d8e
commit a866f39210
2 changed files with 68 additions and 26 deletions

View file

@ -55,13 +55,15 @@ namespace {
#endif // USE_BOOST_FACETS #endif // USE_BOOST_FACETS
public: public:
bool has_year; date_traits_t traits;
bool has_day;
bool input; bool input;
temporal_io_t(const char * _fmt_str, bool _input) temporal_io_t(const char * _fmt_str, bool _input)
: fmt_str(_fmt_str), has_year(icontains(fmt_str, "%y")), : fmt_str(_fmt_str),
has_day(icontains(fmt_str, "%d")), input(_input) { traits(icontains(fmt_str, "%y"),
icontains(fmt_str, "%m") || icontains(fmt_str, "%b"),
icontains(fmt_str, "%d")),
input(_input) {
#if defined(USE_BOOST_FACETS) #if defined(USE_BOOST_FACETS)
if (input) { if (input) {
input_facet = new InputFacetType(fmt_str); input_facet = new InputFacetType(fmt_str);
@ -75,9 +77,10 @@ namespace {
void set_format(const char * fmt) { void set_format(const char * fmt) {
fmt_str = fmt; fmt_str = fmt;
has_year = icontains(fmt_str, "%y"); traits = date_traits_t(icontains(fmt_str, "%y"),
has_day = icontains(fmt_str, "%d"); icontains(fmt_str, "%m") ||
icontains(fmt_str, "%b"),
icontains(fmt_str, "%d"));
#if defined(USE_BOOST_FACETS) #if defined(USE_BOOST_FACETS)
if (input) if (input)
input_facet->format(fmt_str); input_facet->format(fmt_str);
@ -192,7 +195,7 @@ namespace {
date_t parse_date_mask_routine(const char * date_str, date_io_t& io, date_t parse_date_mask_routine(const char * date_str, date_io_t& io,
optional<date_t::year_type> year, optional<date_t::year_type> year,
bool& saw_year, bool& saw_day) date_traits_t * traits = NULL)
{ {
date_t when; date_t when;
@ -214,38 +217,34 @@ namespace {
DEBUG("times.parse", "Parsed date string: " << date_str); DEBUG("times.parse", "Parsed date string: " << date_str);
DEBUG("times.parse", "Parsed result is: " << when); DEBUG("times.parse", "Parsed result is: " << when);
if (! io.has_year) { if (traits)
saw_year = false; *traits = io.traits;
if (! io.traits.has_year) {
when = date_t(year ? *year : CURRENT_DATE().year(), when = date_t(year ? *year : CURRENT_DATE().year(),
when.month(), when.day()); when.month(), when.day());
if (when.month() > CURRENT_DATE().month()) if (when.month() > CURRENT_DATE().month())
when -= gregorian::years(1); when -= gregorian::years(1);
} }
else {
saw_year = true;
}
saw_day = io.has_day;
} }
return when; return when;
} }
date_t parse_date_mask(const char * date_str, date_t parse_date_mask(const char * date_str,
optional<date_t::year_type> year, optional<date_t::year_type> year,
bool& saw_year, bool& saw_day) date_traits_t * traits = NULL)
{ {
if (input_date_io.get()) { if (input_date_io.get()) {
date_t when = parse_date_mask_routine(date_str, *input_date_io.get(), date_t when = parse_date_mask_routine(date_str, *input_date_io.get(),
year, saw_year, saw_day); year, traits);
if (! when.is_not_a_date()) if (! when.is_not_a_date())
return when; return when;
} }
foreach (shared_ptr<date_io_t>& reader, readers) { foreach (shared_ptr<date_io_t>& reader, readers) {
date_t when = parse_date_mask_routine(date_str, *reader.get(), date_t when = parse_date_mask_routine(date_str, *reader.get(),
year, saw_year, saw_day); year, traits);
if (! when.is_not_a_date()) if (! when.is_not_a_date())
return when; return when;
} }
@ -316,9 +315,7 @@ datetime_t parse_datetime(const char * str, optional<date_t::year_type>)
date_t parse_date(const char * str, optional<date_t::year_type> current_year) date_t parse_date(const char * str, optional<date_t::year_type> current_year)
{ {
bool saw_year; return parse_date_mask(str, current_year);
bool saw_day;
return parse_date_mask(str, current_year, saw_year, saw_day);
} }
std::ostream& operator<<(std::ostream& out, std::ostream& operator<<(std::ostream& out,
@ -555,9 +552,8 @@ namespace {
date_t * begin, date_t * begin,
date_t * end) date_t * end)
{ {
bool saw_year = true; date_traits_t traits;
bool saw_day = true; date_t when = parse_date_mask(word.c_str(), none, &traits);
date_t when = parse_date_mask(word.c_str(), none, saw_year, saw_day);
if (when.is_not_a_date()) if (when.is_not_a_date())
throw_(date_error, _("Could not parse date mask: %1") << word); throw_(date_error, _("Could not parse date mask: %1") << word);
@ -566,10 +562,12 @@ namespace {
*begin = when; *begin = when;
if (end) { if (end) {
if (saw_day) if (traits.has_day)
*end = *begin + gregorian::days(1); *end = *begin + gregorian::days(1);
else else if (traits.has_month)
*end = *begin + gregorian::months(1); *end = *begin + gregorian::months(1);
else
*end = *begin + gregorian::years(1);
} }
} }
else if (end) { else if (end) {

View file

@ -138,6 +138,50 @@ inline void to_xml(std::ostream& out, const date_t& when,
} }
} }
struct date_traits_t
{
bool has_year;
bool has_month;
bool has_day;
date_traits_t(bool _has_year = false,
bool _has_month = false,
bool _has_day = false)
: has_year(_has_year), has_month(_has_month), has_day(_has_day) {}
date_traits_t(const date_traits_t& traits)
: has_year(traits.has_year),
has_month(traits.has_month),
has_day(traits.has_day) {}
date_traits_t& operator=(const date_traits_t& traits) {
has_year = traits.has_year;
has_month = traits.has_month;
has_day = traits.has_day;
return *this;
}
bool operator==(const date_traits_t& traits) const {
return (has_year == traits.has_year &&
has_month == traits.has_month &&
has_day == traits.has_day);
}
#if defined(HAVE_BOOST_SERIALIZATION)
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & has_year;
ar & has_month;
ar & has_day;
}
#endif // HAVE_BOOST_SERIALIZATION
};
class date_interval_t : public equality_comparable<date_interval_t> class date_interval_t : public equality_comparable<date_interval_t>
{ {
public: public: