summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--commodity.cc6
-rw-r--r--commodity.h19
-rw-r--r--derive.cc4
-rw-r--r--emacs.cc2
-rw-r--r--entry.cc5
-rw-r--r--entry.h14
-rw-r--r--format.cc6
-rw-r--r--gnucash.cc2
-rw-r--r--journal.cc3
-rw-r--r--op.cc8
-rw-r--r--qif.cc3
-rw-r--r--reconcile.h11
-rw-r--r--report.cc6
-rw-r--r--session.h1
-rw-r--r--test/numerics/t_commodity.cc14
-rw-r--r--textual.cc18
-rw-r--r--times.cc123
-rw-r--r--times.h73
-rw-r--r--utils.cc2
-rw-r--r--value.cc92
-rw-r--r--value.h30
-rw-r--r--walk.cc58
-rw-r--r--walk.h16
-rw-r--r--xact.cc4
-rw-r--r--xact.h34
-rw-r--r--xml.cc4
26 files changed, 308 insertions, 250 deletions
diff --git a/commodity.cc b/commodity.cc
index 81259c8b..a1c1e2c9 100644
--- a/commodity.cc
+++ b/commodity.cc
@@ -182,7 +182,7 @@ amount_t commodity_t::exchange(const amount_t& amount,
basis_cost = final_cost;
amount_t ann_amount(amount);
- ann_amount.annotate(annotation_t(per_unit_cost, moment, tag));
+ ann_amount.annotate(annotation_t(per_unit_cost, moment->date(), tag));
return ann_amount;
}
@@ -324,7 +324,7 @@ void annotation_t::parse(std::istream& in)
else
throw_(amount_error, "Commodity date lacks closing bracket");
- date = parse_datetime(buf);
+ date = parse_date(buf);
}
else if (c == '(') {
if (tag)
@@ -458,7 +458,7 @@ bool compare_amount_commodities::operator()(const amount_t * left,
return false;
if (aleftcomm.details.date && arightcomm.details.date) {
- duration_t diff = *aleftcomm.details.date - *arightcomm.details.date;
+ date_duration_t diff = *aleftcomm.details.date - *arightcomm.details.date;
return diff.is_negative();
}
diff --git a/commodity.h b/commodity.h
index 94aa6b08..2f5ce258 100644
--- a/commodity.h
+++ b/commodity.h
@@ -225,16 +225,15 @@ inline std::ostream& operator<<(std::ostream& out, const commodity_t& comm) {
struct annotation_t : public equality_comparable<annotation_t>
{
- optional<amount_t> price;
- optional<datetime_t> date;
- optional<string> tag;
-
- explicit annotation_t
- (const optional<amount_t>& _price = none,
- const optional<datetime_t>& _date = none,
- const optional<string>& _tag = none)
+ optional<amount_t> price;
+ optional<date_t> date;
+ optional<string> tag;
+
+ explicit annotation_t(const optional<amount_t>& _price = none,
+ const optional<date_t>& _date = none,
+ const optional<string>& _tag = none)
: price(_price), date(_date), tag(_tag) {
- TRACE_CTOR(annotation_t, "const optional<amount_t>& + datetime_t + string");
+ TRACE_CTOR(annotation_t, "const optional<amount_t>& + date_t + string");
}
annotation_t(const annotation_t& other)
: price(other.price), date(other.date), tag(other.tag) {
@@ -258,7 +257,7 @@ struct annotation_t : public equality_comparable<annotation_t>
void parse(std::istream& in);
void print(std::ostream& out) const {
out << "price " << (price ? price->to_string() : "NONE") << " "
- << "date " << (date ? *date : datetime_t()) << " "
+ << "date " << (date ? *date : date_t()) << " "
<< "tag " << (tag ? *tag : "NONE");
}
diff --git a/derive.cc b/derive.cc
index 03b05619..49cddda3 100644
--- a/derive.cc
+++ b/derive.cc
@@ -14,9 +14,7 @@ entry_t * derive_new_entry(report_t& report,
entry_t * matching = NULL;
- // jww (2008-04-20): Need to parse the string here
- //added->_date = *i++;
- added->_date = boost::posix_time::time_from_string(*i++);
+ added->_date = parse_date(*i++);
if (i == end)
throw std::runtime_error("Too few arguments to 'entry'");
diff --git a/emacs.cc b/emacs.cc
index bc039290..688e59af 100644
--- a/emacs.cc
+++ b/emacs.cc
@@ -13,7 +13,7 @@ void format_emacs_xacts::write_entry(entry_t& entry)
out << (static_cast<unsigned long>(entry.beg_line) + 1) << " ";
- tm when = boost::posix_time::to_tm(entry.date());
+ tm when = gregorian::to_tm(entry.date());
std::time_t date = std::mktime(&when); // jww (2008-04-20): Is this GMT or local?
out << "(" << (date / 65536) << " " << (date % 65536) << " 0) ";
diff --git a/entry.cc b/entry.cc
index 562c6fa7..287f6555 100644
--- a/entry.cc
+++ b/entry.cc
@@ -275,8 +275,9 @@ bool entry_base_t::finalize()
amount_t final_cost;
amount_t basis_cost;
amount_t ann_amount =
- commodity_t::exchange(x_amt, final_cost, basis_cost,
- xact->cost, none, xact->actual_date(),
+ commodity_t::exchange(x_amt, final_cost, basis_cost, xact->cost, none,
+ datetime_t(xact->actual_date(),
+ time_duration_t(0, 0, 0)),
entry ? entry->code : optional<string>());
if (xact->amount.annotated()) {
diff --git a/entry.h b/entry.h
index a5df0ba4..fdc9fbee 100644
--- a/entry.h
+++ b/entry.h
@@ -81,10 +81,10 @@ public:
class entry_t : public entry_base_t, public scope_t
{
public:
- datetime_t _date;
- optional<datetime_t> _date_eff;
- optional<string> code;
- string payee;
+ date_t _date;
+ optional<date_t> _date_eff;
+ optional<string> code;
+ string payee;
entry_t() {
TRACE_CTOR(entry_t, "");
@@ -95,15 +95,15 @@ public:
TRACE_DTOR(entry_t);
}
- datetime_t actual_date() const {
+ date_t actual_date() const {
return _date;
}
- datetime_t effective_date() const {
+ date_t effective_date() const {
if (! _date_eff)
return _date;
return *_date_eff;
}
- datetime_t date() const {
+ date_t date() const {
if (xact_t::use_effective_date)
return effective_date();
else
diff --git a/format.cc b/format.cc
index 007233e3..70683e48 100644
--- a/format.cc
+++ b/format.cc
@@ -476,12 +476,12 @@ void format_t::format(std::ostream& out_str, scope_t& scope) const
break;
case element_t::DATE_STRING:
- out << format_datetime(scope.resolve("date").as_datetime());
+ out << format_date(scope.resolve("date").as_date());
break;
case element_t::COMPLETE_DATE_STRING: {
- datetime_t actual_date;
- datetime_t effective_date;
+ date_t actual_date;
+ date_t effective_date;
if (details.xact) {
actual_date = details.xact->actual_date();
effective_date = details.xact->effective_date();
diff --git a/gnucash.cc b/gnucash.cc
index 7849f81f..a834e29a 100644
--- a/gnucash.cc
+++ b/gnucash.cc
@@ -274,7 +274,7 @@ static void dataHandler(void *userData, const char *s, int len)
break;
case ENTRY_DATE:
- curr_entry->_date = parse_datetime(string(s, len));
+ curr_entry->_date = parse_date(string(s, len));
break;
case ENTRY_DESC:
diff --git a/journal.cc b/journal.cc
index c648baf8..7d95d72f 100644
--- a/journal.cc
+++ b/journal.cc
@@ -105,7 +105,8 @@ bool journal_t::add_entry(entry_t * entry)
foreach (const xact_t * xact, entry->xacts)
if (xact->cost) {
assert(xact->amount);
- xact->amount.commodity().add_price(entry->date(),
+ xact->amount.commodity().add_price(datetime_t(entry->date(),
+ time_duration_t(0, 0, 0)),
*xact->cost / xact->amount.number());
}
diff --git a/op.cc b/op.cc
index 0eaf386c..4e7f9e6f 100644
--- a/op.cc
+++ b/op.cc
@@ -298,16 +298,16 @@ void expr_t::op_t::compute(value_t& result,
throw compute_error("Invalid date passed to year|month|day(date)");
}
- const datetime_t& moment(result.as_datetime());
+ const date_t& moment(result.as_date());
switch (kind) {
case F_YEAR:
- result = (long)moment.date().year();
+ result = (long)moment.year();
break;
case F_MONTH:
- result = (long)moment.date().month();
+ result = (long)moment.month();
break;
case F_DAY:
- result = (long)moment.date().day();
+ result = (long)moment.day();
break;
default:
break;
diff --git a/qif.cc b/qif.cc
index ee9318d2..643db562 100644
--- a/qif.cc
+++ b/qif.cc
@@ -98,7 +98,8 @@ unsigned int qif_parser_t::parse(std::istream& in,
case 'D':
SET_BEG_POS_AND_LINE();
get_line(in);
- entry->_date = parse_datetime(line);
+ // jww (2008-08-01): Is this just a date?
+ entry->_date = parse_date(line);
break;
case 'T':
diff --git a/reconcile.h b/reconcile.h
index c6affb81..ab15c15c 100644
--- a/reconcile.h
+++ b/reconcile.h
@@ -9,20 +9,19 @@ namespace ledger {
class reconcile_xacts : public item_handler<xact_t>
{
value_t balance;
- datetime_t cutoff;
-
+ date_t cutoff;
xacts_list xacts;
reconcile_xacts();
public:
- reconcile_xacts(xact_handler_ptr handler,
- const value_t& _balance,
- const datetime_t& _cutoff)
+ reconcile_xacts(xact_handler_ptr handler,
+ const value_t& _balance,
+ const date_t& _cutoff)
: item_handler<xact_t>(handler),
balance(_balance), cutoff(_cutoff) {
TRACE_CTOR(reconcile_xacts,
- "xact_handler_ptr, const value_t&, const datetime_t&");
+ "xact_handler_ptr, const value_t&, const date_t&");
}
virtual ~reconcile_xacts() throw() {
TRACE_DTOR(reconcile_xacts);
diff --git a/report.cc b/report.cc
index dd821c22..5b74806a 100644
--- a/report.cc
+++ b/report.cc
@@ -87,9 +87,9 @@ report_t::chain_xact_handlers(xact_handler_ptr base_handler,
// xacts which can be reconciled to a given balance
// (calculated against the xacts which it receives).
if (! reconcile_balance.empty()) {
- datetime_t cutoff = current_moment;
+ date_t cutoff = current_date;
if (! reconcile_date.empty())
- cutoff = parse_datetime(reconcile_date);
+ cutoff = parse_date(reconcile_date);
handler.reset(new reconcile_xacts
(handler, value_t(reconcile_balance), cutoff));
}
@@ -309,7 +309,7 @@ value_t report_t::ftime(call_scope_t& args)
if (args.size() < 1)
throw_(std::logic_error, "usage: ftime(DATE [, DATE_FORMAT])");
- datetime_t date = args[0].as_datetime();
+ date_t date = args[0].as_date();
string date_format;
if (args.size() == 2)
diff --git a/session.h b/session.h
index 0eeb1e27..bb7c6538 100644
--- a/session.h
+++ b/session.h
@@ -73,6 +73,7 @@ public:
bool cache_dirty;
datetime_t now;
+ date_t today;
#if 0
elision_style_t elision_style;
diff --git a/test/numerics/t_commodity.cc b/test/numerics/t_commodity.cc
index 03acafc1..a96bed72 100644
--- a/test/numerics/t_commodity.cc
+++ b/test/numerics/t_commodity.cc
@@ -11,12 +11,12 @@ void CommodityTestCase::tearDown() {
void CommodityTestCase::testPriceHistory()
{
- ptime jan17_07 = parse_datetime("2007/01/17 00:00:00");
- ptime feb27_07 = parse_datetime("2007/02/27 18:00:00");
- ptime feb28_07 = parse_datetime("2007/02/28 06:00:00");
- ptime feb28_07sbm = parse_datetime("2007/02/28 11:59:59");
- ptime mar01_07 = parse_datetime("2007/03/01 00:00:00");
- ptime apr15_07 = parse_datetime("2007/04/15 13:00:00");
+ datetime_t jan17_07 = parse_datetime("2007/01/17 00:00:00");
+ datetime_t feb27_07 = parse_datetime("2007/02/27 18:00:00");
+ datetime_t feb28_07 = parse_datetime("2007/02/28 06:00:00");
+ datetime_t feb28_07sbm = parse_datetime("2007/02/28 11:59:59");
+ datetime_t mar01_07 = parse_datetime("2007/03/01 00:00:00");
+ datetime_t apr15_07 = parse_datetime("2007/04/15 13:00:00");
// jww (2007-04-17): tbd
amount_t x0;
@@ -40,7 +40,7 @@ void CommodityTestCase::testPriceHistory()
assertTrue(amt1);
assertEqual(amount_t("$1831.83"), *amt1);
- optional<amount_t> amt2 = x1.value(current_moment);
+ optional<amount_t> amt2 = x1.value(current_time);
assertTrue(amt2);
assertEqual(amount_t("$2124.12"), *amt2);
diff --git a/textual.cc b/textual.cc
index aaa96007..c7f80f3f 100644
--- a/textual.cc
+++ b/textual.cc
@@ -384,10 +384,10 @@ xact_t * parse_xact(char * line, account_t * account,
if (char * p = std::strchr(buf, '=')) {
*p++ = '\0';
- xact->_date_eff = parse_datetime(p);
+ xact->_date_eff = parse_date(p);
}
if (buf[0])
- xact->_date = parse_datetime(buf);
+ xact->_date = parse_date(buf);
}
}
}
@@ -455,9 +455,9 @@ entry_t * parse_entry(std::istream& in, char * line, account_t * master,
if (char * p = std::strchr(line, '=')) {
*p++ = '\0';
- curr->_date_eff = parse_datetime(p);
+ curr->_date_eff = parse_date(p);
}
- curr->_date = parse_datetime(line);
+ curr->_date = parse_date(line);
// Parse the optional cleared flag: *
@@ -624,16 +624,16 @@ static void clock_out_from_timelog(std::list<time_entry_t>& time_entries,
}
std::auto_ptr<entry_t> curr(new entry_t);
- curr->_date = when;
+ curr->_date = when.date();
curr->code = desc ? desc : "";
curr->payee = event.desc;
- if (curr->_date < event.checkin)
+ if (when < event.checkin)
throw parse_error
("Timelog check-out date less than corresponding check-in");
char buf[32];
- std::sprintf(buf, "%lds", long((curr->_date - event.checkin).seconds()));
+ std::sprintf(buf, "%lds", long((when - event.checkin).seconds()));
amount_t amt;
amt.parse(buf);
assert(amt.valid());
@@ -993,8 +993,8 @@ unsigned int textual_parser_t::parse(std::istream& in,
accounts.push_back(time_entry.account);
foreach (account_t * account, accounts)
- clock_out_from_timelog(time_entries, current_moment, account,
- NULL, journal);
+ clock_out_from_timelog(time_entries, current_time, account, NULL,
+ journal);
assert(time_entries.empty());
}
diff --git a/times.cc b/times.cc
index 772158fb..ccec34fa 100644
--- a/times.cc
+++ b/times.cc
@@ -33,48 +33,42 @@
namespace ledger {
+namespace {
#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
-const ptime time_now = boost::posix_time::microsec_clock::universal_time();
+ const ptime time_now = boost::posix_time::microsec_clock::universal_time();
#else
-const ptime time_now = boost::posix_time::second_clock::universal_time();
+ const ptime time_now = boost::posix_time::second_clock::universal_time();
#endif
-const date date_now = boost::gregorian::day_clock::universal_day();
+ const date date_now = boost::gregorian::day_clock::universal_day();
+}
-#ifdef SUPPORT_DATE_AND_TIME
-const datetime_t& current_moment(time_now);
-#else
-const datetime_t& current_moment(date_now);
-#endif
+const datetime_t& current_time(time_now);
+const date_t& current_date(date_now);
+ int current_year(current_date.year());
-int current_year(current_moment.date().year());
+namespace {
+ const char * formats[] = {
+ "%y/%m/%d",
+ "%Y/%m/%d",
+ "%m/%d",
+ "%y.%m.%d",
+ "%Y.%m.%d",
+ "%m.%d",
+ "%y-%m-%d",
+ "%Y-%m-%d",
+ "%m-%d",
+ "%a",
+ "%A",
+ "%b",
+ "%B",
+ "%Y",
+ NULL
+ };
+}
-string input_time_format;
string output_time_format = "%Y/%m/%d";
#if 0
-static const char * formats[] = {
- "%y/%m/%d",
- "%Y/%m/%d",
- "%m/%d",
- "%y.%m.%d",
- "%Y.%m.%d",
- "%m.%d",
- "%y-%m-%d",
- "%Y-%m-%d",
- "%m-%d",
- "%a",
- "%A",
- "%b",
- "%B",
- "%Y",
- NULL
-};
-#endif
-
-bool day_before_month = false;
-static bool day_before_month_initialized = false;
-
-#if 0
datetime_t datetime_t::now(std::time(NULL));
namespace {
@@ -94,14 +88,6 @@ namespace {
datetime_t parse_datetime(const char * str)
{
- if (! day_before_month_initialized) {
-#ifdef HAVE_NL_LANGINFO
- const char * d_fmt = nl_langinfo(D_FMT);
- if (d_fmt && std::strlen(d_fmt) > 1 && d_fmt[1] == 'd')
- day_before_month = true;
- day_before_month_initialized = true;
-#endif
- }
#if 0
return parse_abs_datetime(in);
#else
@@ -120,9 +106,9 @@ datetime_t parse_datetime(const char * str)
#endif
}
-datetime_t interval_t::first(const datetime_t& moment) const
+date_t interval_t::first(const date_t& moment) const
{
- datetime_t quant(begin);
+ date_t quant(begin);
if (! advanced)
advanced = true;
@@ -147,7 +133,7 @@ datetime_t interval_t::first(const datetime_t& moment) const
quant = std::mktime(desc);
- datetime_t temp;
+ date_t temp;
while (moment >= (temp = increment(quant))) {
if (quant == temp)
break;
@@ -159,40 +145,27 @@ datetime_t interval_t::first(const datetime_t& moment) const
return quant;
}
-datetime_t interval_t::increment(const datetime_t& moment) const
+date_t interval_t::increment(const date_t& moment) const
{
-#if 0
- struct std::tm * desc = std::localtime(&moment.when);
+ date_t future(moment);
- if (years)
- desc->tm_year += years;
- if (months)
- desc->tm_mon += months;
- if (days)
- desc->tm_mday += days;
+ if (years) future += gregorian::years(years);
+ if (months) future += gregorian::years(months);
+ if (days) future += gregorian::years(days);
- desc->tm_hour += hours;
- desc->tm_min += minutes;
- desc->tm_sec += seconds;
-
- desc->tm_isdst = -1;
-
- return std::mktime(desc);
-#else
- return datetime_t();
-#endif
+ return future;
}
namespace {
void parse_inclusion_specifier(const string& word,
- datetime_t * begin, datetime_t * end)
+ date_t * begin, date_t * end)
{
#if 0
// jww (2008-05-08): Implement!
struct std::tm when;
if (! parse_date_mask(word.c_str(), &when))
- throw_(datetime_error, "Could not parse date mask: " << word);
+ throw_(date_error, "Could not parse date mask: " << word);
when.tm_hour = 0;
when.tm_min = 0;
@@ -244,7 +217,7 @@ namespace {
}
void parse_date_words(std::istream& in, string& word,
- datetime_t * begin, datetime_t * end)
+ date_t * begin, date_t * end)
{
string type;
@@ -264,7 +237,7 @@ namespace {
if (word == "month") {
#if 0
// jww (2008-05-08):
- std::strftime(buf, 31, "%B", datetime_t::now.localtime());
+ std::strftime(buf, 31, "%B", date_t::now.localtime());
#endif
word = buf;
mon_spec = true;
@@ -272,7 +245,7 @@ namespace {
else if (word == "year") {
#if 0
// jww (2008-05-08):
- std::strftime(buf, 31, "%Y", datetime_t::now.localtime());
+ std::strftime(buf, 31, "%Y", date_t::now.localtime());
#endif
word = buf;
}
@@ -329,12 +302,6 @@ void interval_t::parse(std::istream& in)
months = 3 * quantity;
else if (word == "years")
years = quantity;
- else if (word == "hours")
- hours = quantity;
- else if (word == "minutes")
- minutes = quantity;
- else if (word == "seconds")
- seconds = quantity;
}
else if (word == "day")
days = 1;
@@ -346,12 +313,6 @@ void interval_t::parse(std::istream& in)
months = 3;
else if (word == "year")
years = 1;
- else if (word == "hour")
- hours = 1;
- else if (word == "minute")
- minutes = 1;
- else if (word == "second")
- seconds = 1;
}
else if (word == "daily")
days = 1;
@@ -367,8 +328,6 @@ void interval_t::parse(std::istream& in)
months = 3;
else if (word == "yearly")
years = 1;
- else if (word == "hourly")
- hours = 1;
else if (word == "this" || word == "last" || word == "next") {
parse_date_words(in, word, &begin, &end);
}
diff --git a/times.h b/times.h
index ba765027..4ae665be 100644
--- a/times.h
+++ b/times.h
@@ -34,65 +34,50 @@
namespace ledger {
-#define SUPPORT_DATE_AND_TIME 1
-#ifdef SUPPORT_DATE_AND_TIME
+DECLARE_EXCEPTION(datetime_error, std::runtime_error);
+DECLARE_EXCEPTION(date_error, std::runtime_error);
typedef boost::posix_time::ptime datetime_t;
-typedef datetime_t::time_duration_type duration_t;
+typedef datetime_t::time_duration_type time_duration_t;
inline bool is_valid(const datetime_t& moment) {
return ! moment.is_not_a_date_time();
}
-#else // SUPPORT_DATE_AND_TIME
-
-typedef boost::gregorian::date datetime_t;
-typedef boost::gregorian::date_duration duration_t;
+typedef boost::gregorian::date date_t;
+typedef boost::gregorian::date_duration date_duration_t;
-inline bool is_valid(const datetime_t& moment) {
+inline bool is_valid(const date_t& moment) {
return ! moment.is_not_a_date();
}
-#endif // SUPPORT_DATE_AND_TIME
-
-extern const datetime_t& current_moment;
-
-extern int current_year;
-extern string input_time_format;
-extern string output_time_format;
-
-DECLARE_EXCEPTION(datetime_error, std::runtime_error);
+extern const datetime_t& current_time;
+extern const date_t& current_date;
+extern int current_year;
+extern string input_time_format;
+extern string output_time_format;
struct interval_t
{
unsigned short years;
unsigned short months;
unsigned short days;
- unsigned short hours;
- unsigned short minutes;
- unsigned short seconds;
-
- datetime_t begin;
- datetime_t end;
-
+ date_t begin;
+ date_t end;
mutable bool advanced;
interval_t(int _days = 0, int _months = 0, int _years = 0,
- const datetime_t& _begin = datetime_t(),
- const datetime_t& _end = datetime_t())
+ const date_t& _begin = date_t(),
+ const date_t& _end = date_t())
: years(_years), months(_months), days(_days),
- hours(0), minutes(0), seconds(0),
begin(_begin), end(_end), advanced(false) {
TRACE_CTOR(interval_t,
- "int, int, int, const datetime_t&, const datetime_t&");
+ "int, int, int, const date_t&, const date_t&");
}
interval_t(const interval_t& other)
: years(other.years),
months(other.months),
days(other.days),
- hours(other.hours),
- minutes(other.minutes),
- seconds(other.seconds),
begin(other.begin),
end(other.end),
@@ -103,7 +88,6 @@ struct interval_t
interval_t(const string& desc)
: years(0), months(0), days(0),
- hours(0), minutes(0), seconds(0),
begin(), end(), advanced(false) {
TRACE_CTOR(interval_t, "const string&");
std::istringstream stream(desc);
@@ -115,18 +99,16 @@ struct interval_t
}
operator bool() const {
- return (years > 0 || months > 0 || days > 0 ||
- hours > 0 || minutes > 0 || seconds > 0);
+ return years > 0 || months > 0 || days > 0;
}
- void start(const datetime_t& moment) {
+ void start(const date_t& moment) {
begin = first(moment);
}
- datetime_t first(const datetime_t& moment = datetime_t()) const;
-
- datetime_t increment(const datetime_t&) const;
+ date_t first(const date_t& moment = date_t()) const;
+ date_t increment(const date_t&) const;
- void parse(std::istream& in);
+ void parse(std::istream& in);
};
#if 0
@@ -147,11 +129,14 @@ inline datetime_t ptime_from_local_time_string(const string& time_string) {
}
#endif
-datetime_t parse_datetime(const char * str);
-
inline datetime_t parse_datetime(const string& str) {
return parse_datetime(str.c_str());
}
+datetime_t parse_datetime(const char * str);
+
+inline date_t parse_date(const string& str) {
+ return gregorian::from_string(str);
+}
inline std::time_t to_time_t(const ptime& t)
{
@@ -171,9 +156,9 @@ inline string format_datetime(const datetime_t& when) {
return buf;
}
-extern const ptime time_now;
-extern const date date_now;
-extern bool day_before_month;
+inline string format_date(const date_t& when) {
+ return to_iso_extended_string(when);
+}
#if 0
struct intorchar
diff --git a/utils.cc b/utils.cc
index 9a6eb7d0..5ac5cef0 100644
--- a/utils.cc
+++ b/utils.cc
@@ -467,7 +467,7 @@ bool logger_func(log_level_t level)
IF_VERIFY()
*_log_stream << " TIME OBJSZ MEMSZ" << std::endl;
- appender = (logger_start - current_moment).total_milliseconds();
+ appender = (logger_start - current_time).total_milliseconds();
}
*_log_stream << std::right << std::setw(5)
diff --git a/value.cc b/value.cc
index 1f8d4823..797f3e55 100644
--- a/value.cc
+++ b/value.cc
@@ -48,6 +48,11 @@ value_t::storage_t& value_t::storage_t::operator=(const value_t::storage_t& rhs)
(const_cast<char *>(rhs.data)));
break;
+ case DATE:
+ new(reinterpret_cast<date_t *>(data))
+ date_t(*reinterpret_cast<date_t *>(const_cast<char *>(rhs.data)));
+ break;
+
case AMOUNT:
new(reinterpret_cast<amount_t *>(data))
amount_t(*reinterpret_cast<amount_t *>
@@ -130,6 +135,7 @@ void value_t::initialize()
#if 0
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(bool));
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(datetime_t));
+ BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(date_t));
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(long));
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(amount_t));
BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(balance_t *));
@@ -143,6 +149,8 @@ void value_t::initialize()
<< " sizeof(bool)");
DEBUG_(std::setw(3) << std::right << sizeof(datetime_t)
<< " sizeof(datetime_t)");
+ DEBUG_(std::setw(3) << std::right << sizeof(date_t)
+ << " sizeof(date_t)");
DEBUG_(std::setw(3) << std::right << sizeof(long)
<< " sizeof(long)");
DEBUG_(std::setw(3) << std::right << sizeof(amount_t)
@@ -179,6 +187,8 @@ value_t::operator bool() const
return as_boolean();
case DATETIME:
return is_valid(as_datetime());
+ case DATE:
+ return is_valid(as_date());
case INTEGER:
return as_long();
case AMOUNT:
@@ -223,6 +233,17 @@ datetime_t value_t::to_datetime() const
}
}
+date_t value_t::to_date() const
+{
+ if (is_date()) {
+ return as_date();
+ } else {
+ value_t temp(*this);
+ temp.in_place_cast(DATE);
+ return temp.as_date();
+ }
+}
+
long value_t::to_long() const
{
if (is_long()) {
@@ -356,6 +377,19 @@ value_t& value_t::operator+=(const value_t& val)
}
break;
+ case DATE:
+ switch (val.type()) {
+ case INTEGER:
+ as_date_lval() += date_duration_t(val.as_long());
+ return *this;
+ case AMOUNT:
+ as_date_lval() += date_duration_t(val.as_amount().to_long());
+ return *this;
+ default:
+ break;
+ }
+ break;
+
case INTEGER:
switch (val.type()) {
case INTEGER:
@@ -494,6 +528,19 @@ value_t& value_t::operator-=(const value_t& val)
}
break;
+ case DATE:
+ switch (val.type()) {
+ case INTEGER:
+ as_date_lval() -= date_duration_t(val.as_long());
+ return *this;
+ case AMOUNT:
+ as_date_lval() -= date_duration_t(val.as_amount().to_long());
+ return *this;
+ default:
+ break;
+ }
+ break;
+
case INTEGER:
switch (val.type()) {
case INTEGER:
@@ -798,6 +845,11 @@ bool value_t::operator==(const value_t& val) const
return as_datetime() == val.as_datetime();
break;
+ case DATE:
+ if (val.is_date())
+ return as_date() == val.as_date();
+ break;
+
case INTEGER:
switch (val.type()) {
case INTEGER:
@@ -885,6 +937,11 @@ bool value_t::operator<(const value_t& val) const
return as_datetime() < val.as_datetime();
break;
+ case DATE:
+ if (val.is_date())
+ return as_date() < val.as_date();
+ break;
+
case INTEGER:
switch (val.type()) {
case INTEGER:
@@ -930,6 +987,11 @@ bool value_t::operator>(const value_t& val) const
return as_datetime() > val.as_datetime();
break;
+ case DATE:
+ if (val.is_date())
+ return as_date() > val.as_date();
+ break;
+
case INTEGER:
switch (val.type()) {
case INTEGER:
@@ -1142,6 +1204,9 @@ void value_t::in_place_negate()
case DATETIME:
set_long(- as_long());
return;
+ case DATE:
+ set_long(- as_long());
+ return;
case AMOUNT:
as_amount_lval().in_place_negate();
return;
@@ -1167,6 +1232,8 @@ bool value_t::is_realzero() const
return as_long() == 0;
case DATETIME:
return ! is_valid(as_datetime());
+ case DATE:
+ return ! is_valid(as_date());
case AMOUNT:
return as_amount().is_realzero();
case BALANCE:
@@ -1198,6 +1265,8 @@ bool value_t::is_zero() const
return as_long() == 0;
case DATETIME:
return ! is_valid(as_datetime());
+ case DATE:
+ return ! is_valid(as_date());
case AMOUNT:
return as_amount().is_zero();
case BALANCE:
@@ -1353,6 +1422,8 @@ value_t value_t::annotated_date() const
switch (type()) {
case DATETIME:
return *this;
+ case DATE:
+ return *this;
case AMOUNT: {
optional<datetime_t> temp = as_amount().annotation_details().date;
@@ -1400,6 +1471,7 @@ value_t value_t::strip_annotations(const bool keep_price,
case BOOLEAN:
case INTEGER:
case DATETIME:
+ case DATE:
case STRING:
case POINTER:
return *this;
@@ -1505,6 +1577,10 @@ void value_t::dump(std::ostream& out, const int first_width,
out << as_datetime();
break;
+ case DATE:
+ out << as_date();
+ break;
+
case INTEGER:
out << as_long();
break;
@@ -1580,7 +1656,10 @@ void value_t::print(std::ostream& out, const bool relaxed) const
break;
case DATETIME:
- out << '[' << format_datetime(as_datetime()) << ']';
+ assert(false);
+ break;
+ case DATE:
+ out << '[' << format_date(as_date()) << ']';
break;
case STRING:
@@ -1623,6 +1702,12 @@ void value_t::read(const char *& data)
set_datetime(read_long<unsigned long>(data));
#endif
break;
+ case DATE:
+#if 0
+ // jww (2008-04-22): I need to record and read a date_t directly
+ set_date(read_long<unsigned long>(data));
+#endif
+ break;
case AMOUNT: {
amount_t temp;
temp.read(data);
@@ -1652,6 +1737,11 @@ void value_t::write(std::ostream& out) const
binary::write_number(out, as_datetime());
#endif
break;
+ case DATE:
+#if 0
+ binary::write_number(out, as_date());
+#endif
+ break;
case AMOUNT:
as_amount().write(out);
break;
diff --git a/value.h b/value.h
index 35a44828..4754de61 100644
--- a/value.h
+++ b/value.h
@@ -102,6 +102,7 @@ public:
VOID, // a null value (i.e., uninitialized)
BOOLEAN, // a boolean
DATETIME, // a date and time (Boost posix_time)
+ DATE, // a date (Boost gregorian::date)
INTEGER, // a signed integer value
AMOUNT, // a ledger::amount_t
BALANCE, // a ledger::balance_t
@@ -267,10 +268,14 @@ public:
set_boolean(val);
}
- value_t(const datetime_t val) {
- TRACE_CTOR(value_t, "const datetime_t");
+ value_t(const datetime_t& val) {
+ TRACE_CTOR(value_t, "const datetime_t&");
set_datetime(val);
}
+ value_t(const date_t& val) {
+ TRACE_CTOR(value_t, "const date_t&");
+ set_date(val);
+ }
value_t(const long val) {
TRACE_CTOR(value_t, "const long");
@@ -459,6 +464,7 @@ public:
* is_boolean()
* is_long()
* is_datetime()
+ * is_date()
* is_amount()
* is_balance()
* is_balance_pair()
@@ -514,6 +520,23 @@ public:
new(reinterpret_cast<datetime_t *>(storage->data)) datetime_t(val);
}
+ bool is_date() const {
+ return is_type(DATE);
+ }
+ date_t& as_date_lval() {
+ assert(is_date());
+ _dup();
+ return *reinterpret_cast<date_t *>(storage->data);
+ }
+ const date_t& as_date() const {
+ assert(is_date());
+ return *reinterpret_cast<date_t *>(storage->data);
+ }
+ void set_date(const date_t& val) {
+ set_type(DATE);
+ new(reinterpret_cast<date_t *>(storage->data)) date_t(val);
+ }
+
bool is_long() const {
return is_type(INTEGER);
}
@@ -695,6 +718,7 @@ public:
bool to_boolean() const;
long to_long() const;
datetime_t to_datetime() const;
+ date_t to_date() const;
amount_t to_amount() const;
balance_t to_balance() const;
balance_pair_t to_balance_pair() const;
@@ -828,6 +852,8 @@ public:
return "a boolean";
case DATETIME:
return "a date/time";
+ case DATE:
+ return "a date";
case INTEGER:
return "an integer";
case AMOUNT:
diff --git a/walk.cc b/walk.cc
index 44d5ca3b..20fde04d 100644
--- a/walk.cc
+++ b/walk.cc
@@ -242,7 +242,7 @@ void handle_value(const value_t& value,
unsigned int flags,
std::list<xact_t>& temps,
item_handler<xact_t>& handler,
- const datetime_t& date = datetime_t(),
+ const date_t& date = date_t(),
xacts_list * component_xacts = NULL)
{
temps.push_back(xact_t(account));
@@ -278,6 +278,7 @@ void handle_value(const value_t& value,
switch (value.type()) {
case value_t::BOOLEAN:
case value_t::DATETIME:
+ case value_t::DATE:
case value_t::INTEGER:
temp.cast(value_t::AMOUNT);
// fall through...
@@ -372,11 +373,11 @@ void related_xacts::flush()
item_handler<xact_t>::flush();
}
-void changed_value_xacts::output_diff(const datetime_t& current)
+void changed_value_xacts::output_diff(const date_t& date)
{
value_t cur_bal;
- xact_xdata(*last_xact).date = current;
+ xact_xdata(*last_xact).date = date;
#if 0
compute_total(cur_bal, details_t(*last_xact));
#endif
@@ -390,7 +391,7 @@ void changed_value_xacts::output_diff(const datetime_t& current)
entry_temps.push_back(entry_t());
entry_t& entry = entry_temps.back();
entry.payee = "Commodities revalued";
- entry._date = current;
+ entry._date = date;
handle_value(diff, NULL, &entry, XACT_NO_TOTAL, xact_temps,
*handler);
@@ -400,12 +401,12 @@ void changed_value_xacts::output_diff(const datetime_t& current)
void changed_value_xacts::operator()(xact_t& xact)
{
if (last_xact) {
- datetime_t moment;
+ date_t date;
if (xact_has_xdata(*last_xact))
- moment = xact_xdata_(*last_xact).date;
+ date = xact_xdata_(*last_xact).date;
else
- moment = xact.date();
- output_diff(moment);
+ date = xact.date();
+ output_diff(date);
}
if (changed_values_only)
@@ -497,18 +498,13 @@ void subtotal_xacts::operator()(xact_t& xact)
account_xdata(*xact_account(xact)).dflags |= ACCOUNT_HAS_UNB_VIRTUALS;
}
-void interval_xacts::report_subtotal(const datetime_t& moment)
+void interval_xacts::report_subtotal(const date_t& date)
{
assert(last_xact);
start = interval.begin;
- if (is_valid(moment))
- // jww (2008-04-24): How to change this back into a datetime?
-#if 0
- finish = moment - 86400L;
-#else
- ;
-#endif
+ if (is_valid(date))
+ finish = date - gregorian::days(1);
else
finish = last_xact->date();
@@ -519,7 +515,7 @@ void interval_xacts::report_subtotal(const datetime_t& moment)
void interval_xacts::operator()(xact_t& xact)
{
- const datetime_t date = xact.date();
+ const date_t& date(xact.date());
if ((is_valid(interval.begin) && date < interval.begin) ||
(is_valid(interval.end) && date >= interval.end))
@@ -533,12 +529,12 @@ void interval_xacts::operator()(xact_t& xact)
started = true;
}
- datetime_t quant = interval.increment(interval.begin);
+ date_t quant = interval.increment(interval.begin);
if (date >= quant) {
if (last_xact)
report_subtotal(quant);
- datetime_t temp;
+ date_t temp;
while (date >= (temp = interval.increment(quant))) {
if (quant == temp)
break;
@@ -670,7 +666,7 @@ void generate_xacts::add_xact(const interval_t& period,
pending_xacts.push_back(pending_xacts_pair(period, &xact));
}
-void budget_xacts::report_budget_items(const datetime_t& moment)
+void budget_xacts::report_budget_items(const date_t& date)
{
if (pending_xacts.size() == 0)
return;
@@ -679,13 +675,13 @@ void budget_xacts::report_budget_items(const datetime_t& moment)
do {
reported = false;
foreach (pending_xacts_list::value_type& pair, pending_xacts) {
- datetime_t& begin = pair.first.begin;
+ date_t& begin = pair.first.begin;
if (! is_valid(begin)) {
- pair.first.start(moment);
+ pair.first.start(date);
begin = pair.first.begin;
}
- if (begin < moment &&
+ if (begin < date &&
(! is_valid(pair.first.end) || begin < pair.first.end)) {
xact_t& xact = *pair.second;
@@ -694,7 +690,7 @@ void budget_xacts::report_budget_items(const datetime_t& moment)
#if 0
// jww (2008-04-24): Need a new debug macro here
DEBUG_TIME("ledger.walk.budget", begin);
- DEBUG_TIME("ledger.walk.budget", moment);
+ DEBUG_TIME("ledger.walk.budget", date);
#endif
entry_temps.push_back(entry_t());
@@ -753,10 +749,10 @@ void forecast_xacts::add_xact(const interval_t& period, xact_t& xact)
interval_t& i = pending_xacts.back().first;
if (! is_valid(i.begin)) {
- i.start(current_moment);
+ i.start(current_date);
i.begin = i.increment(i.begin);
} else {
- while (i.begin < current_moment)
+ while (i.begin < current_date)
i.begin = i.increment(i.begin);
}
}
@@ -764,7 +760,7 @@ void forecast_xacts::add_xact(const interval_t& period, xact_t& xact)
void forecast_xacts::flush()
{
xacts_list passed;
- datetime_t last;
+ date_t last;
while (pending_xacts.size() > 0) {
pending_xacts_list::iterator least = pending_xacts.begin();
@@ -774,7 +770,7 @@ void forecast_xacts::flush()
if ((*i).first.begin < (*least).first.begin)
least = i;
- datetime_t& begin = (*least).first.begin;
+ date_t& begin = (*least).first.begin;
if (is_valid((*least).first.end) && begin >= (*least).first.end) {
pending_xacts.erase(least);
@@ -795,11 +791,13 @@ void forecast_xacts::flush()
temp.add_flags(XACT_AUTO | XACT_TEMP);
entry.add_xact(&temp);
- datetime_t next = (*least).first.increment(begin);
+ date_t next = (*least).first.increment(begin);
+#if 0
// jww (2008-04-24): Does seconds() here give the total seconds?
if (next < begin || // wraparound
(is_valid(last) && (next - last).seconds() > 365 * 5 * 24 * 3600))
break;
+#endif
begin = next;
item_handler<xact_t>::operator()(temp);
@@ -957,7 +955,7 @@ void walk_commodities(commodity_pool_t::commodities_by_ident& commodities,
if ((*i)->history())
foreach (const commodity_t::history_map::value_type& pair,
(*i)->history()->prices) {
- entry_temps.back()._date = pair.first;
+ entry_temps.back()._date = pair.first.date();
xact_temps.push_back(xact_t(&acct_temps.back()));
xact_t& temp = xact_temps.back();
diff --git a/walk.h b/walk.h
index 7984e62c..fe08918b 100644
--- a/walk.h
+++ b/walk.h
@@ -98,7 +98,7 @@ struct xact_xdata_t : public noncopyable
value_t value;
unsigned int index;
unsigned short dflags;
- datetime_t date;
+ date_t date;
account_t * account;
void * ptr;
xacts_list * component_xacts;
@@ -609,13 +609,13 @@ public:
virtual void flush() {
if (last_xact) {
- output_diff(current_moment);
+ output_diff(current_date);
last_xact = NULL;
}
item_handler<xact_t>::flush();
}
- void output_diff(const datetime_t& current);
+ void output_diff(const date_t& current);
virtual void operator()(xact_t& xact);
};
@@ -661,8 +661,8 @@ protected:
std::list<xact_t> xact_temps;
public:
- datetime_t start;
- datetime_t finish;
+ date_t start;
+ date_t finish;
subtotal_xacts(xact_handler_ptr handler,
bool _remember_components = false)
@@ -715,7 +715,7 @@ public:
TRACE_DTOR(interval_xacts);
}
- void report_subtotal(const datetime_t& moment = datetime_t());
+ void report_subtotal(const date_t& moment = date_t());
virtual void flush() {
if (last_xact)
@@ -807,7 +807,7 @@ public:
virtual void flush();
virtual void operator()(xact_t& xact) {
- days_of_the_week[xact.date().date().day_of_week()].push_back(&xact);
+ days_of_the_week[xact.date().day_of_week()].push_back(&xact);
}
};
@@ -860,7 +860,7 @@ public:
TRACE_DTOR(budget_xacts);
}
- void report_budget_items(const datetime_t& moment);
+ void report_budget_items(const date_t& date);
virtual void operator()(xact_t& xact);
};
diff --git a/xact.cc b/xact.cc
index d0360f7f..29c5e63d 100644
--- a/xact.cc
+++ b/xact.cc
@@ -42,14 +42,14 @@ xact_t::~xact_t()
TRACE_DTOR(xact_t);
}
-datetime_t xact_t::actual_date() const
+date_t xact_t::actual_date() const
{
if (! _date && entry)
return entry->actual_date();
return *_date;
}
-datetime_t xact_t::effective_date() const
+date_t xact_t::effective_date() const
{
if (! _date_eff && entry)
return entry->effective_date();
diff --git a/xact.h b/xact.h
index a597876d..d843bd11 100644
--- a/xact.h
+++ b/xact.h
@@ -55,20 +55,20 @@ class xact_t : public supports_flags<>, public scope_t
public:
enum state_t { UNCLEARED, CLEARED, PENDING };
- entry_t * entry;
- state_t state;
- account_t * account;
- optional<datetime_t> _date;
- optional<datetime_t> _date_eff;
- amount_t amount;
- optional<expr_t> amount_expr;
- optional<amount_t> cost;
- optional<expr_t> cost_expr;
- optional<string> note;
- istream_pos_type beg_pos;
- unsigned long beg_line;
- istream_pos_type end_pos;
- unsigned long end_line;
+ entry_t * entry;
+ state_t state;
+ account_t * account;
+ optional<date_t> _date;
+ optional<date_t> _date_eff;
+ amount_t amount;
+ optional<expr_t> amount_expr;
+ optional<amount_t> cost;
+ optional<expr_t> cost_expr;
+ optional<string> note;
+ istream_pos_type beg_pos;
+ unsigned long beg_line;
+ istream_pos_type end_pos;
+ unsigned long end_line;
mutable void * data;
static bool use_effective_date;
@@ -113,9 +113,9 @@ class xact_t : public supports_flags<>, public scope_t
}
~xact_t();
- datetime_t actual_date() const;
- datetime_t effective_date() const;
- datetime_t date() const {
+ date_t actual_date() const;
+ date_t effective_date() const;
+ date_t date() const {
if (use_effective_date)
return effective_date();
else
diff --git a/xml.cc b/xml.cc
index c65fa190..ebafd65b 100644
--- a/xml.cc
+++ b/xml.cc
@@ -70,10 +70,10 @@ static void endElement(void *userData, const char *name)
curr_entry = NULL;
}
else if (std::strcmp(name, "en:date") == 0) {
- curr_entry->_date = parse_datetime(data);
+ curr_entry->_date = parse_date(data);
}
else if (std::strcmp(name, "en:date_eff") == 0) {
- curr_entry->_date_eff = parse_datetime(data);
+ curr_entry->_date_eff = parse_date(data);
}
else if (std::strcmp(name, "en:code") == 0) {
curr_entry->code = data;