date_interval_t now uses a duration_t object
This is instead of using boost::variant.
This commit is contained in:
parent
4481396913
commit
3a9b7df4e5
2 changed files with 97 additions and 81 deletions
122
src/times.cc
122
src/times.cc
|
|
@ -314,50 +314,18 @@ date_t parse_date(const char * str, optional<date_t::year_type> current_year)
|
||||||
return parse_date_mask(str, current_year, saw_year);
|
return parse_date_mask(str, current_year, saw_year);
|
||||||
}
|
}
|
||||||
|
|
||||||
date_t date_interval_t::add_duration(const date_t& date,
|
|
||||||
const duration_t& duration)
|
|
||||||
{
|
|
||||||
if (duration.type() == typeid(gregorian::days))
|
|
||||||
return date + boost::get<gregorian::days>(duration);
|
|
||||||
else if (duration.type() == typeid(gregorian::weeks))
|
|
||||||
return date + boost::get<gregorian::weeks>(duration);
|
|
||||||
else if (duration.type() == typeid(gregorian::months))
|
|
||||||
return date + boost::get<gregorian::months>(duration);
|
|
||||||
else
|
|
||||||
assert(duration.type() == typeid(gregorian::years));
|
|
||||||
return date + boost::get<gregorian::years>(duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
date_t date_interval_t::subtract_duration(const date_t& date,
|
|
||||||
const duration_t& duration)
|
|
||||||
{
|
|
||||||
if (duration.type() == typeid(gregorian::days))
|
|
||||||
return date - boost::get<gregorian::days>(duration);
|
|
||||||
else if (duration.type() == typeid(gregorian::weeks))
|
|
||||||
return date - boost::get<gregorian::weeks>(duration);
|
|
||||||
else if (duration.type() == typeid(gregorian::months))
|
|
||||||
return date - boost::get<gregorian::months>(duration);
|
|
||||||
else
|
|
||||||
assert(duration.type() == typeid(gregorian::years));
|
|
||||||
return date - boost::get<gregorian::years>(duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out,
|
std::ostream& operator<<(std::ostream& out,
|
||||||
const date_interval_t::duration_t& duration)
|
const date_interval_t::duration_t& duration)
|
||||||
{
|
{
|
||||||
if (duration.type() == typeid(gregorian::days))
|
if (duration.quantum == date_interval_t::duration_t::DAYS)
|
||||||
out << boost::get<gregorian::days>(duration).days()
|
out << duration.length << " day(s)";
|
||||||
<< " day(s)";
|
else if (duration.quantum == date_interval_t::duration_t::WEEKS)
|
||||||
else if (duration.type() == typeid(gregorian::weeks))
|
out << duration.length << " week(s)";
|
||||||
out << (boost::get<gregorian::weeks>(duration).days() / 7)
|
else if (duration.quantum == date_interval_t::duration_t::MONTHS)
|
||||||
<< " week(s)";
|
out << duration.length << " month(s)";
|
||||||
else if (duration.type() == typeid(gregorian::months))
|
|
||||||
out << boost::get<gregorian::months>(duration).number_of_months()
|
|
||||||
<< " month(s)";
|
|
||||||
else {
|
else {
|
||||||
assert(duration.type() == typeid(gregorian::years));
|
assert(duration.quantum == date_interval_t::duration_t::YEARS);
|
||||||
out << boost::get<gregorian::years>(duration).number_of_years()
|
out << duration.length << " year(s)";
|
||||||
<< " year(s)";
|
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
@ -365,7 +333,7 @@ std::ostream& operator<<(std::ostream& out,
|
||||||
void date_interval_t::resolve_end()
|
void date_interval_t::resolve_end()
|
||||||
{
|
{
|
||||||
if (start && ! end_of_duration) {
|
if (start && ! end_of_duration) {
|
||||||
end_of_duration = add_duration(*start, *duration);
|
end_of_duration = duration->add(*start);
|
||||||
DEBUG("times.interval",
|
DEBUG("times.interval",
|
||||||
"stabilize: end_of_duration = " << *end_of_duration);
|
"stabilize: end_of_duration = " << *end_of_duration);
|
||||||
}
|
}
|
||||||
|
|
@ -383,7 +351,7 @@ void date_interval_t::resolve_end()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start && ! next) {
|
if (start && ! next) {
|
||||||
next = add_duration(*start, *skip_duration);
|
next = skip_duration->add(*start);
|
||||||
DEBUG("times.interval",
|
DEBUG("times.interval",
|
||||||
"stabilize: next set to: " << *next);
|
"stabilize: next set to: " << *next);
|
||||||
}
|
}
|
||||||
|
|
@ -423,8 +391,8 @@ void date_interval_t::stabilize(const optional<date_t>& date)
|
||||||
|
|
||||||
date_t when = start ? *start : *date;
|
date_t when = start ? *start : *date;
|
||||||
|
|
||||||
if (duration->type() == typeid(gregorian::months) ||
|
if (duration->quantum == duration_t::MONTHS ||
|
||||||
duration->type() == typeid(gregorian::years)) {
|
duration->quantum == duration_t::YEARS) {
|
||||||
DEBUG("times.interval", "stabilize: monthly or yearly duration");
|
DEBUG("times.interval", "stabilize: monthly or yearly duration");
|
||||||
|
|
||||||
start = date_t(when.year(), gregorian::Jan, 1);
|
start = date_t(when.year(), gregorian::Jan, 1);
|
||||||
|
|
@ -433,7 +401,7 @@ void date_interval_t::stabilize(const optional<date_t>& date)
|
||||||
|
|
||||||
start = date_t(when - gregorian::days(400));
|
start = date_t(when - gregorian::days(400));
|
||||||
|
|
||||||
if (duration->type() == typeid(gregorian::weeks)) {
|
if (duration->quantum == duration_t::WEEKS) {
|
||||||
// Move it to a Sunday
|
// Move it to a Sunday
|
||||||
while (start->day_of_week() != start_of_week)
|
while (start->day_of_week() != start_of_week)
|
||||||
*start += gregorian::days(1);
|
*start += gregorian::days(1);
|
||||||
|
|
@ -540,8 +508,8 @@ bool date_interval_t::find_period(const date_t& date)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
scan = add_duration(scan, *skip_duration);
|
scan = skip_duration->add(scan);
|
||||||
end_of_scan = add_duration(scan, *duration);
|
end_of_scan = duration->add(scan);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -565,7 +533,7 @@ date_interval_t& date_interval_t::operator++()
|
||||||
} else {
|
} else {
|
||||||
start = *next;
|
start = *next;
|
||||||
|
|
||||||
end_of_duration = add_duration(*start, *duration);
|
end_of_duration = duration->add(*start);
|
||||||
}
|
}
|
||||||
|
|
||||||
next = none;
|
next = none;
|
||||||
|
|
@ -634,15 +602,15 @@ namespace {
|
||||||
assert(look_for_start || look_for_end);
|
assert(look_for_start || look_for_end);
|
||||||
|
|
||||||
if (word == _("year")) {
|
if (word == _("year")) {
|
||||||
duration = gregorian::years(1);
|
duration = date_interval_t::duration_t(date_interval_t::duration_t::YEARS, 1);
|
||||||
start = gregorian::date(start.year(), 1, 1);
|
start = gregorian::date(start.year(), 1, 1);
|
||||||
}
|
}
|
||||||
else if (word == _("month")) {
|
else if (word == _("month")) {
|
||||||
duration = gregorian::months(1);
|
duration = date_interval_t::duration_t(date_interval_t::duration_t::MONTHS, 1);
|
||||||
start = gregorian::date(start.year(), start.month(), 1);
|
start = gregorian::date(start.year(), start.month(), 1);
|
||||||
}
|
}
|
||||||
else if (word == _("today") || word == _("day")) {
|
else if (word == _("today") || word == _("day")) {
|
||||||
duration = gregorian::days(1);
|
duration = date_interval_t::duration_t(date_interval_t::duration_t::DAYS, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
parse_specifier = true;
|
parse_specifier = true;
|
||||||
|
|
@ -651,15 +619,15 @@ namespace {
|
||||||
if (parse_specifier)
|
if (parse_specifier)
|
||||||
parse_inclusion_specifier(word, &start, &end);
|
parse_inclusion_specifier(word, &start, &end);
|
||||||
else
|
else
|
||||||
end = date_interval_t::add_duration(start, *duration);
|
end = duration->add(start);
|
||||||
|
|
||||||
if (type == _("last") && duration) {
|
if (type == _("last") && duration) {
|
||||||
start = date_interval_t::subtract_duration(start, *duration);
|
start = duration->subtract(start);
|
||||||
end = date_interval_t::subtract_duration(end, *duration);
|
end = duration->subtract(end);
|
||||||
}
|
}
|
||||||
else if (type == _("next") && duration) {
|
else if (type == _("next") && duration) {
|
||||||
start = date_interval_t::add_duration(start, *duration);
|
start = duration->add(start);
|
||||||
end = date_interval_t::add_duration(end, *duration);
|
end = duration->add(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (look_for_start && is_valid(start)) interval.start = start;
|
if (look_for_start && is_valid(start)) interval.start = start;
|
||||||
|
|
@ -683,41 +651,41 @@ void date_interval_t::parse(std::istream& in)
|
||||||
int quantity = lexical_cast<int>(word);
|
int quantity = lexical_cast<int>(word);
|
||||||
read_lower_word(in, word);
|
read_lower_word(in, word);
|
||||||
if (word == _("days"))
|
if (word == _("days"))
|
||||||
duration = gregorian::days(quantity);
|
duration = duration_t(duration_t::DAYS, quantity);
|
||||||
else if (word == _("weeks"))
|
else if (word == _("weeks"))
|
||||||
duration = gregorian::weeks(quantity);
|
duration = duration_t(duration_t::WEEKS, quantity);
|
||||||
else if (word == _("months"))
|
else if (word == _("months"))
|
||||||
duration = gregorian::months(quantity);
|
duration = duration_t(duration_t::MONTHS, quantity);
|
||||||
else if (word == _("quarters"))
|
else if (word == _("quarters"))
|
||||||
duration = gregorian::months(3 * quantity);
|
duration = duration_t(duration_t::MONTHS, 3 * quantity);
|
||||||
else if (word == _("years"))
|
else if (word == _("years"))
|
||||||
duration = gregorian::years(quantity);
|
duration = duration_t(duration_t::YEARS, quantity);
|
||||||
}
|
}
|
||||||
else if (word == _("day"))
|
else if (word == _("day"))
|
||||||
duration = gregorian::days(1);
|
duration = duration_t(duration_t::DAYS, 1);
|
||||||
else if (word == _("week"))
|
else if (word == _("week"))
|
||||||
duration = gregorian::weeks(1);
|
duration = duration_t(duration_t::WEEKS, 1);
|
||||||
else if (word == _("month"))
|
else if (word == _("month"))
|
||||||
duration = gregorian::months(1);
|
duration = duration_t(duration_t::MONTHS, 1);
|
||||||
else if (word == _("quarter"))
|
else if (word == _("quarter"))
|
||||||
duration = gregorian::months(3);
|
duration = duration_t(duration_t::MONTHS, 3);
|
||||||
else if (word == _("year"))
|
else if (word == _("year"))
|
||||||
duration = gregorian::years(1);
|
duration = duration_t(duration_t::YEARS, 1);
|
||||||
}
|
}
|
||||||
else if (word == _("daily"))
|
else if (word == _("daily"))
|
||||||
duration = gregorian::days(1);
|
duration = duration_t(duration_t::DAYS, 1);
|
||||||
else if (word == _("weekly"))
|
else if (word == _("weekly"))
|
||||||
duration = gregorian::weeks(1);
|
duration = duration_t(duration_t::WEEKS, 1);
|
||||||
else if (word == _("biweekly"))
|
else if (word == _("biweekly"))
|
||||||
duration = gregorian::weeks(2);
|
duration = duration_t(duration_t::WEEKS, 2);
|
||||||
else if (word == _("monthly"))
|
else if (word == _("monthly"))
|
||||||
duration = gregorian::months(1);
|
duration = duration_t(duration_t::MONTHS, 1);
|
||||||
else if (word == _("bimonthly"))
|
else if (word == _("bimonthly"))
|
||||||
duration = gregorian::months(2);
|
duration = duration_t(duration_t::MONTHS, 2);
|
||||||
else if (word == _("quarterly"))
|
else if (word == _("quarterly"))
|
||||||
duration = gregorian::months(3);
|
duration = duration_t(duration_t::MONTHS, 3);
|
||||||
else if (word == _("yearly"))
|
else if (word == _("yearly"))
|
||||||
duration = gregorian::years(1);
|
duration = duration_t(duration_t::YEARS, 1);
|
||||||
else if (word == _("this") || word == _("last") || word == _("next") ||
|
else if (word == _("this") || word == _("last") || word == _("next") ||
|
||||||
word == _("today")) {
|
word == _("today")) {
|
||||||
parse_date_words(in, word, *this);
|
parse_date_words(in, word, *this);
|
||||||
|
|
@ -760,17 +728,17 @@ void date_interval_t::parse(std::istream& in)
|
||||||
|
|
||||||
if (wday) {
|
if (wday) {
|
||||||
while (start->day_of_week() != *wday)
|
while (start->day_of_week() != *wday)
|
||||||
*start -= gregorian::days(1);
|
*start = duration_t(duration_t::DAYS, 1).subtract(*start);
|
||||||
|
|
||||||
if (! end)
|
if (! end)
|
||||||
end = *start + gregorian::days(1);
|
end = duration_t(duration_t::DAYS, 1).add(*start);
|
||||||
} else {
|
} else {
|
||||||
bool overwrite_end = false;
|
bool overwrite_end = false;
|
||||||
|
|
||||||
if (year) {
|
if (year) {
|
||||||
start = date_t(*year, 1, 1);
|
start = date_t(*year, 1, 1);
|
||||||
if (! end) {
|
if (! end) {
|
||||||
end = *start + gregorian::years(1);
|
end = duration_t(duration_t::YEARS, 1).add(*start);
|
||||||
overwrite_end = true;
|
overwrite_end = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -778,7 +746,7 @@ void date_interval_t::parse(std::istream& in)
|
||||||
if (mon) {
|
if (mon) {
|
||||||
start = date_t(start->year(), *mon, 1);
|
start = date_t(start->year(), *mon, 1);
|
||||||
if (! end || overwrite_end)
|
if (! end || overwrite_end)
|
||||||
end = *start + gregorian::months(1);
|
end = duration_t(duration_t::MONTHS, 1).add(*start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
56
src/times.h
56
src/times.h
|
|
@ -119,10 +119,58 @@ void set_input_date_format(const char * format);
|
||||||
class date_interval_t : public equality_comparable<date_interval_t>
|
class date_interval_t : public equality_comparable<date_interval_t>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef variant<gregorian::days,
|
struct duration_t
|
||||||
gregorian::weeks,
|
{
|
||||||
gregorian::months,
|
enum skip_quantum_t {
|
||||||
gregorian::years> duration_t;
|
DAYS, WEEKS, MONTHS, YEARS
|
||||||
|
} quantum;
|
||||||
|
int length;
|
||||||
|
|
||||||
|
duration_t() : quantum(DAYS), length(0) {
|
||||||
|
TRACE_CTOR(date_interval_t::duration_t, "");
|
||||||
|
}
|
||||||
|
duration_t(skip_quantum_t _quantum, int _length)
|
||||||
|
: quantum(_quantum), length(_length) {
|
||||||
|
TRACE_CTOR(date_interval_t::duration_t, "skip_quantum_t, int");
|
||||||
|
}
|
||||||
|
duration_t(const duration_t& dur)
|
||||||
|
: quantum(dur.quantum), length(dur.length) {
|
||||||
|
TRACE_CTOR(date_interval_t::duration_t, "copy");
|
||||||
|
}
|
||||||
|
~duration_t() throw() {
|
||||||
|
TRACE_DTOR(date_interval_t::duration_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
date_t add(const date_t& date) const {
|
||||||
|
switch (quantum) {
|
||||||
|
case DAYS:
|
||||||
|
return date + gregorian::days(length);
|
||||||
|
case WEEKS:
|
||||||
|
return date + gregorian::weeks(length);
|
||||||
|
case MONTHS:
|
||||||
|
return date + gregorian::months(length);
|
||||||
|
case YEARS:
|
||||||
|
return date + gregorian::years(length);
|
||||||
|
default:
|
||||||
|
assert(0); return date_t();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
date_t subtract(const date_t& date) const {
|
||||||
|
switch (quantum) {
|
||||||
|
case DAYS:
|
||||||
|
return date - gregorian::days(length);
|
||||||
|
case WEEKS:
|
||||||
|
return date - gregorian::weeks(length);
|
||||||
|
case MONTHS:
|
||||||
|
return date - gregorian::months(length);
|
||||||
|
case YEARS:
|
||||||
|
return date - gregorian::years(length);
|
||||||
|
default:
|
||||||
|
assert(0); return date_t();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static date_t add_duration(const date_t& date,
|
static date_t add_duration(const date_t& date,
|
||||||
const duration_t& duration);
|
const duration_t& duration);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue