Greatly improved the way "weeks" are iterated
This commit is contained in:
parent
4ff8087815
commit
a93111470d
4 changed files with 61 additions and 34 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
52
src/times.cc
52
src/times.cc
|
|
@ -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")
|
||||||
|
|
|
||||||
21
src/times.h
21
src/times.h
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue