Greatly improved the way "weeks" are iterated

This commit is contained in:
John Wiegley 2009-02-21 02:08:49 -04:00
parent 4ff8087815
commit a93111470d
4 changed files with 61 additions and 34 deletions

View file

@ -124,26 +124,6 @@ namespace {
} }
}; };
short string_to_day_of_week(const std::string& str)
{
if (str == "sun")
return 0;
else if (str == "mon")
return 1;
else if (str == "tue")
return 2;
else if (str == "wed")
return 3;
else if (str == "thu")
return 4;
else if (str == "fri")
return 5;
else if (str == "sat")
return 6;
assert(false);
return -1;
}
entry_template_t entry_template_t
args_to_entry_template(value_t::sequence_t::const_iterator begin, args_to_entry_template(value_t::sequence_t::const_iterator begin,
value_t::sequence_t::const_iterator end) value_t::sequence_t::const_iterator end)

View file

@ -512,7 +512,7 @@ void instance_t::nomarket_directive(char * line)
void instance_t::year_directive(char * line) void instance_t::year_directive(char * line)
{ {
current_year = std::atoi(skip_ws(line + 1)); current_year = lexical_cast<int>(skip_ws(line + 1));
} }
void instance_t::option_directive(char * line) void instance_t::option_directive(char * line)

View file

@ -33,6 +33,7 @@
namespace ledger { namespace ledger {
int start_of_week = 0;
optional<std::string> input_date_format; optional<std::string> input_date_format;
std::string output_datetime_format = "%Y-%m-%d %H:%M:%S"; std::string output_datetime_format = "%Y-%m-%d %H:%M:%S";
std::string output_date_format = "%Y-%m-%d"; std::string output_date_format = "%Y-%m-%d";
@ -58,9 +59,7 @@ namespace {
"%Y", "%Y",
NULL NULL
}; };
}
namespace {
bool parse_date_mask(const char * date_str, std::tm& result) bool parse_date_mask(const char * date_str, std::tm& result)
{ {
if (input_date_format) { if (input_date_format) {
@ -106,6 +105,27 @@ namespace {
} }
} }
int string_to_day_of_week(const std::string& str)
{
if (str == "sun" || str == "sunday" || str == "0")
return 0;
else if (str == "mon" || str == "monday" || str == "1")
return 1;
else if (str == "tue" || str == "tuesday" || str == "2")
return 2;
else if (str == "wed" || str == "wednesday" || str == "3")
return 3;
else if (str == "thu" || str == "thursday" || str == "4")
return 4;
else if (str == "fri" || str == "friday" || str == "5")
return 5;
else if (str == "sat" || str == "saturday" || str == "6")
return 6;
assert(false);
return -1;
}
datetime_t parse_datetime(const char * str, int) datetime_t parse_datetime(const char * str, int)
{ {
std::tm when; std::tm when;
@ -130,7 +150,19 @@ date_t interval_t::first(const optional<date_t>& moment)
// a date early enough that the range will be correct, but late enough // a date early enough that the range will be correct, but late enough
// that we don't spend hundreds of thousands of loops skipping through // that we don't spend hundreds of thousands of loops skipping through
// time. // time.
begin = date_t(moment->year(), gregorian::Jan, 1); assert(moment);
if (months > 0 || years > 0) {
begin = date_t(moment->year(), gregorian::Jan, 1);
} else {
begin = date_t(*moment - gregorian::days(400));
// jww (2009-02-21): Add support for starting a week on any day
if (weekly) { // move it to a Sunday
while (begin.day_of_week() != start_of_week)
begin += gregorian::days(1);
}
}
} }
date_t quant(begin); date_t quant(begin);
@ -281,12 +313,14 @@ void interval_t::parse(std::istream& in)
if (word == "every") { if (word == "every") {
read_lower_word(in, word); read_lower_word(in, word);
if (std::isdigit(word[0])) { if (std::isdigit(word[0])) {
int quantity = std::atol(word.c_str()); int quantity = lexical_cast<int>(word);
read_lower_word(in, word); read_lower_word(in, word);
if (word == "days") if (word == "days")
days = quantity; days = quantity;
else if (word == "weeks") else if (word == "weeks") {
days = 7 * quantity; days = 7 * quantity;
weekly = true;
}
else if (word == "months") else if (word == "months")
months = quantity; months = quantity;
else if (word == "quarters") else if (word == "quarters")
@ -296,8 +330,10 @@ void interval_t::parse(std::istream& in)
} }
else if (word == "day") else if (word == "day")
days = 1; days = 1;
else if (word == "week") else if (word == "week") {
days = 7; days = 7;
weekly = true;
}
else if (word == "month") else if (word == "month")
months = 1; months = 1;
else if (word == "quarter") else if (word == "quarter")
@ -307,8 +343,10 @@ void interval_t::parse(std::istream& in)
} }
else if (word == "daily") else if (word == "daily")
days = 1; days = 1;
else if (word == "weekly") else if (word == "weekly") {
days = 7; days = 7;
weekly = true;
}
else if (word == "biweekly") else if (word == "biweekly")
days = 14; days = 14;
else if (word == "monthly") else if (word == "monthly")

View file

@ -70,8 +70,11 @@ inline bool is_valid(const date_t& moment) {
#endif #endif
#define CURRENT_DATE() boost::gregorian::day_clock::universal_day() #define CURRENT_DATE() boost::gregorian::day_clock::universal_day()
extern int start_of_week;
extern optional<std::string> input_date_format; extern optional<std::string> input_date_format;
int string_to_day_of_week(const std::string& str);
datetime_t parse_datetime(const char * str, int current_year = -1); datetime_t parse_datetime(const char * str, int current_year = -1);
inline datetime_t parse_datetime(const std::string& str, int current_year = -1) { inline datetime_t parse_datetime(const std::string& str, int current_year = -1) {
@ -128,26 +131,32 @@ struct interval_t
int years; int years;
int months; int months;
int days; int days;
bool weekly;
date_t begin; date_t begin;
date_t end; date_t end;
interval_t(int _days = 0, int _months = 0, int _years = 0, interval_t(int _days = 0,
const date_t& _begin = date_t(), int _months = 0,
const date_t& _end = date_t()) int _years = 0,
bool _weekly = false,
const date_t& _begin = date_t(),
const date_t& _end = date_t())
: years(_years), months(_months), days(_days), : years(_years), months(_months), days(_days),
begin(_begin), end(_end) { weekly(_weekly), begin(_begin), end(_end) {
TRACE_CTOR(interval_t, "int, int, int, const date_t&, const date_t&"); TRACE_CTOR(interval_t,
"int, int, int, bool, const date_t&, const date_t&");
} }
interval_t(const interval_t& other) interval_t(const interval_t& other)
: years(other.years), : years(other.years),
months(other.months), months(other.months),
days(other.days), days(other.days),
weekly(other.weekly),
begin(other.begin), begin(other.begin),
end(other.end) { end(other.end) {
TRACE_CTOR(interval_t, "copy"); TRACE_CTOR(interval_t, "copy");
} }
interval_t(const string& desc) interval_t(const string& desc)
: years(0), months(0), days(0), begin(), end() { : years(0), months(0), days(0), weekly(false), begin(), end() {
TRACE_CTOR(interval_t, "const string&"); TRACE_CTOR(interval_t, "const string&");
std::istringstream stream(desc); std::istringstream stream(desc);
parse(stream); parse(stream);