summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2004-08-18 02:15:31 -0400
committerJohn Wiegley <johnw@newartisans.com>2004-08-18 02:15:31 -0400
commit8af33274fbb9cf0c9a4a452b77825ab6e519cf8d (patch)
tree20cade7c1ab8986db969a17e823168829b97c3f7
parent9d1bdd0989996318825a458e01b7b0eb5f48397f (diff)
downloadfork-ledger-8af33274fbb9cf0c9a4a452b77825ab6e519cf8d.tar.gz
fork-ledger-8af33274fbb9cf0c9a4a452b77825ab6e519cf8d.tar.bz2
fork-ledger-8af33274fbb9cf0c9a4a452b77825ab6e519cf8d.zip
more time interval support: last month, last feb, next year, etc.
-rw-r--r--datetime.cc62
-rw-r--r--datetime.h13
-rw-r--r--debug.h8
-rw-r--r--format.cc2
-rw-r--r--main.cc58
-rw-r--r--textual.cc4
-rw-r--r--walk.cc6
-rw-r--r--walk.h2
8 files changed, 101 insertions, 54 deletions
diff --git a/datetime.cc b/datetime.cc
index baa0bd2c..0714c4ad 100644
--- a/datetime.cc
+++ b/datetime.cc
@@ -5,8 +5,8 @@
namespace ledger {
-std::time_t now = std::time(NULL);
-struct std::tm * now_tm = std::localtime(&now);
+std::time_t now = std::time(NULL);
+int now_year = std::localtime(&now)->tm_year;
static std::time_t base = -1;
static int base_year = -1;
@@ -35,9 +35,11 @@ std::time_t interval_t::increment(const std::time_t moment)
std::time_t then = moment;
if (years || months) {
- struct std::tm * desc = std::gmtime(&then);
+ struct std::tm * desc = std::localtime(&then);
+
if (years)
desc->tm_year += years;
+
if (months) {
desc->tm_mon += months;
@@ -45,7 +47,12 @@ std::time_t interval_t::increment(const std::time_t moment)
desc->tm_year++;
desc->tm_mon -= 12;
}
+ else if (desc->tm_mon < 0) {
+ desc->tm_year--;
+ desc->tm_mon += 12;
+ }
}
+
then = std::mktime(desc);
}
@@ -69,7 +76,7 @@ static void parse_inclusion_specifier(const std::string& word,
bool saw_mon = true;
if (when.tm_year == -1) {
- when.tm_year = now_tm->tm_year;
+ when.tm_year = now_year;
saw_year = false;
}
if (when.tm_mon == -1) {
@@ -135,6 +142,47 @@ interval_t * interval_t::parse(std::istream& in,
months = 3;
else if (word == "yearly")
years = 1;
+ else if (word == "this" || word == "last" || word == "next") {
+ std::string type = word;
+ bool mon_spec = false;
+ char buf[32];
+
+ if (! in.eof())
+ in >> word;
+ else
+ word = "month";
+
+ if (word == "month") {
+ std::strftime(buf, 31, "%B", std::localtime(&now));
+ word = buf;
+ mon_spec = true;
+ }
+ else if (word == "year") {
+ std::strftime(buf, 31, "%Y", std::localtime(&now));
+ word = buf;
+ }
+
+ parse_inclusion_specifier(word, begin, end);
+
+ if (type == "last") {
+ if (mon_spec) {
+ *begin = interval_t(0, -1, 0).increment(*begin);
+ *end = interval_t(0, -1, 0).increment(*end);
+ } else {
+ *begin = interval_t(0, 0, -1).increment(*begin);
+ *end = interval_t(0, 0, -1).increment(*end);
+ }
+ }
+ else if (type == "next") {
+ if (mon_spec) {
+ *begin = interval_t(0, 1, 0).increment(*begin);
+ *end = interval_t(0, 1, 0).increment(*end);
+ } else {
+ *begin = interval_t(0, 0, 1).increment(*begin);
+ *end = interval_t(0, 0, 1).increment(*end);
+ }
+ }
+ }
else if (word == "in") {
in >> word;
parse_inclusion_specifier(word, begin, end);
@@ -180,7 +228,7 @@ bool parse_date(const char * date_str, std::time_t * result, const int year)
when.tm_sec = 0;
if (when.tm_year == -1)
- when.tm_year = ((year == -1) ? now_tm->tm_year : (year - 1900));
+ when.tm_year = ((year == -1) ? now_year : (year - 1900));
if (when.tm_mon == -1)
when.tm_mon = 0;
@@ -225,8 +273,8 @@ bool quick_parse_date(char * date_str, std::time_t * result)
struct std::tm when;
std::memset(&when, 0, sizeof(when));
- base_year = year == -1 ? now_tm->tm_year + 1900 : year;
- when.tm_year = year == -1 ? now_tm->tm_year : year - 1900;
+ base_year = year == -1 ? now_year + 1900 : year;
+ when.tm_year = year == -1 ? now_year : year - 1900;
when.tm_mday = 1;
base = std::mktime(&when);
diff --git a/datetime.h b/datetime.h
index bc32032a..6f6ad1df 100644
--- a/datetime.h
+++ b/datetime.h
@@ -9,12 +9,11 @@ namespace ledger {
struct interval_t
{
- unsigned long years;
- unsigned long months;
- unsigned long seconds;
+ int years;
+ int months;
+ int seconds;
- interval_t(unsigned long _seconds, unsigned long _months = 0,
- unsigned long _years = 0)
+ interval_t(int _seconds, int _months = 0, int _years = 0)
: years(_years), months(_months), seconds(_seconds) {}
std::time_t increment(const std::time_t);
@@ -23,8 +22,8 @@ struct interval_t
std::time_t * end);
};
-extern std::time_t now;
-extern struct std::tm * now_tm;
+extern std::time_t now;
+extern int now_year;
bool parse_date_mask(const char * date_str, struct std::tm * result);
diff --git a/debug.h b/debug.h
index 047741c2..75c7b5b3 100644
--- a/debug.h
+++ b/debug.h
@@ -92,10 +92,10 @@ inline bool _debug_active(const char * const cls) {
}
#define DEBUG_PRINT_(x) DEBUG_PRINT(_debug_cls, x)
-#define DEBUG_PRINT_TIME(cls, x) { \
- char buf[256]; \
- std::strftime(buf, 255, "%Y/%m/%d", std::gmtime(&x)); \
- DEBUG_PRINT(cls, #x << " is " << buf); \
+#define DEBUG_PRINT_TIME(cls, x) { \
+ char buf[256]; \
+ std::strftime(buf, 255, "%Y/%m/%d", std::localtime(&x)); \
+ DEBUG_PRINT(cls, #x << " is " << buf); \
}
#define DEBUG_PRINT_TIME_(x) DEBUG_PRINT_TIME(_debug_cls, x)
diff --git a/format.cc b/format.cc
index af5ebbbc..d917877c 100644
--- a/format.cc
+++ b/format.cc
@@ -223,7 +223,7 @@ void format_t::format_elements(std::ostream& out,
if (details.entry && details.entry->date != -1) {
char buf[256];
std::strftime(buf, 255, elem->chars.c_str(),
- std::gmtime(&details.entry->date));
+ std::localtime(&details.entry->date));
out << (elem->max_width == 0 ? buf : truncated(buf, elem->max_width));
} else {
out << " ";
diff --git a/main.cc b/main.cc
index 6e0bb524..82a739c8 100644
--- a/main.cc
+++ b/main.cc
@@ -365,35 +365,6 @@ int main(int argc, char * argv[], char * envp[])
show_all_related = true;
}
- // Compile the format strings
-
- const char * f;
- if (! config->format_string.empty())
- f = config->format_string.c_str();
- else if (command == "b")
- f = bal_fmt.c_str();
- else if (command == "r")
- f = reg_fmt.c_str();
- else if (command == "E")
- f = equity_fmt.c_str();
- else
- f = print_fmt.c_str();
-
- std::string first_line_format;
- std::string next_lines_format;
-
- if (const char * p = std::strstr(f, "%/")) {
- first_line_format = std::string(f, 0, p - f);
- next_lines_format = std::string(p + 2);
- } else {
- first_line_format = next_lines_format = f;
- }
-
- format_t format(first_line_format);
- format_t nformat(next_lines_format);
-
- TIMER_STOP(handle_options);
-
// Setup a few local and global variables, depending on the config
// settings.
@@ -453,6 +424,35 @@ int main(int argc, char * argv[], char * envp[])
"disp-pred: " << config->display_predicate);
#endif
+ // Compile the format strings
+
+ const char * f;
+ if (! config->format_string.empty())
+ f = config->format_string.c_str();
+ else if (command == "b")
+ f = bal_fmt.c_str();
+ else if (command == "r")
+ f = reg_fmt.c_str();
+ else if (command == "E")
+ f = equity_fmt.c_str();
+ else
+ f = print_fmt.c_str();
+
+ std::string first_line_format;
+ std::string next_lines_format;
+
+ if (const char * p = std::strstr(f, "%/")) {
+ first_line_format = std::string(f, 0, p - f);
+ next_lines_format = std::string(p + 2);
+ } else {
+ first_line_format = next_lines_format = f;
+ }
+
+ format_t format(first_line_format);
+ format_t nformat(next_lines_format);
+
+ TIMER_STOP(handle_options);
+
// Walk the entries based on the report type and the options
TIMER_START(report_gen);
diff --git a/textual.cc b/textual.cc
index 88a1720a..df7d0242 100644
--- a/textual.cc
+++ b/textual.cc
@@ -476,8 +476,8 @@ unsigned int parse_textual_journal(std::istream& in, journal_t * journal,
case 'Y': // set the current year
in >> c;
- in >> now_tm->tm_year;
- now_tm->tm_year -= 1900;
+ in >> now_year;
+ now_year -= 1900;
break;
#ifdef TIMELOG_SUPPORT
diff --git a/walk.cc b/walk.cc
index 8b7c583a..c77647d6 100644
--- a/walk.cc
+++ b/walk.cc
@@ -132,9 +132,9 @@ void subtotal_transactions::flush(const char * spec_fmt)
if (start != finish)
finish -= 86400;
- std::strftime(buf, 255, fmt.c_str(), std::gmtime(&finish));
+ std::strftime(buf, 255, fmt.c_str(), std::localtime(&finish));
} else {
- std::strftime(buf, 255, spec_fmt, std::gmtime(&finish));
+ std::strftime(buf, 255, spec_fmt, std::localtime(&finish));
}
entry_t * entry = new entry_t;
@@ -199,7 +199,7 @@ void interval_transactions::operator()(transaction_t * xact)
}
if (! interval.seconds) {
- struct std::tm * desc = std::gmtime(&xact->entry->date);
+ struct std::tm * desc = std::localtime(&xact->entry->date);
if (interval.years)
desc->tm_mon = 0;
desc->tm_mday = 1;
diff --git a/walk.h b/walk.h
index 232eea35..bced95d6 100644
--- a/walk.h
+++ b/walk.h
@@ -327,7 +327,7 @@ class dow_transactions : public subtotal_transactions
virtual void flush();
virtual void operator()(transaction_t * xact) {
- struct std::tm * desc = std::gmtime(&xact->entry->date);
+ struct std::tm * desc = std::localtime(&xact->entry->date);
days_of_the_week[desc->tm_wday].push_back(xact);
}
};