summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am6
-rw-r--r--Makefile.in44
-rw-r--r--acconf.h.in6
-rw-r--r--amount.cc93
-rw-r--r--amount.h148
-rw-r--r--balance.cc13
-rw-r--r--balance.h8
-rw-r--r--binary.cc6
-rwxr-xr-xconfigure191
-rw-r--r--configure.in48
-rw-r--r--datetime.cc575
-rw-r--r--datetime.h320
-rw-r--r--debug.h2
-rw-r--r--derive.cc1
-rw-r--r--gnucash.cc2
-rw-r--r--journal.cc7
-rw-r--r--journal.h22
-rw-r--r--ledger.h1
-rw-r--r--ofx.cc1
-rw-r--r--py_amount.cc6
-rw-r--r--py_eval.cc2
-rw-r--r--qif.cc1
-rw-r--r--quotes.cc25
-rw-r--r--quotes.h10
-rw-r--r--report.cc4
-rw-r--r--session.cc2
-rw-r--r--session.h4
-rw-r--r--tests/corelib/numerics/Commodity.cc15
-rw-r--r--textual.cc17
-rw-r--r--times.cc7
-rw-r--r--times.h41
-rw-r--r--trace.cc4
-rw-r--r--value.cc164
-rw-r--r--value.h102
-rw-r--r--xml.cc1
35 files changed, 567 insertions, 1332 deletions
diff --git a/Makefile.am b/Makefile.am
index 4d5aa886..5de2dd82 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,10 +13,10 @@ endif
libledger_la_CXXFLAGS = $(WARNFLAGS) -I$(top_builddir)/gdtoa
libledger_la_SOURCES = \
amount.cc \
+ times.cc \
quotes.cc \
balance.cc \
value.cc \
- datetime.cc \
xml.cc \
xpath.cc \
mask.cc \
@@ -76,10 +76,10 @@ libpyledger_la_LDFLAGS = -release 3.0
pkginclude_HEADERS = \
amount.h \
+ times.h \
balance.h \
binary.h \
csv.h \
- datetime.h \
debug.h \
derive.h \
emacs.h \
@@ -151,7 +151,7 @@ noinst_PROGRAMS = ledger.so
ledger_so_SOURCES = pyledger.cc
-PYLIBS = pyledger ledger gdtoa boost_python gmp pcre
+PYLIBS = pyledger ledger gdtoa boost_date_time boost_python gmp pcre
if HAVE_EXPAT
PYLIBS += expat
diff --git a/Makefile.in b/Makefile.in
index bf8e69c8..a7600bda 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -89,8 +89,8 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libledger_la_LIBADD =
-am__libledger_la_SOURCES_DIST = amount.cc quotes.cc balance.cc \
- value.cc datetime.cc xml.cc xpath.cc mask.cc format.cc util.cc \
+am__libledger_la_SOURCES_DIST = amount.cc times.cc quotes.cc \
+ balance.cc value.cc xml.cc xpath.cc mask.cc format.cc util.cc \
session.cc journal.cc parser.cc textual.cc binary.cc \
xmlparse.cc qif.cc report.cc transform.cc csv.cc derive.cc \
emacs.cc reconcile.cc gnucash.cc ofx.cc debug.cc trace.cc
@@ -99,10 +99,10 @@ am__libledger_la_SOURCES_DIST = amount.cc quotes.cc balance.cc \
@HAVE_LIBOFX_TRUE@am__objects_3 = libledger_la-ofx.lo
@DEBUG_TRUE@am__objects_4 = libledger_la-debug.lo \
@DEBUG_TRUE@ libledger_la-trace.lo
-am_libledger_la_OBJECTS = libledger_la-amount.lo \
+am_libledger_la_OBJECTS = libledger_la-amount.lo libledger_la-times.lo \
libledger_la-quotes.lo libledger_la-balance.lo \
- libledger_la-value.lo libledger_la-datetime.lo \
- libledger_la-xml.lo libledger_la-xpath.lo libledger_la-mask.lo \
+ libledger_la-value.lo libledger_la-xml.lo \
+ libledger_la-xpath.lo libledger_la-mask.lo \
libledger_la-format.lo libledger_la-util.lo \
libledger_la-session.lo libledger_la-journal.lo \
libledger_la-parser.lo libledger_la-textual.lo \
@@ -341,12 +341,12 @@ lib_LTLIBRARIES = libledger.la $(am__append_1)
libledger_la_CXXFLAGS = $(WARNFLAGS) -I$(top_builddir)/gdtoa \
$(am__append_2) $(am__append_4) $(am__append_6) \
$(am__append_8) $(am__append_10)
-libledger_la_SOURCES = amount.cc quotes.cc balance.cc value.cc \
- datetime.cc xml.cc xpath.cc mask.cc format.cc util.cc \
- session.cc journal.cc parser.cc textual.cc binary.cc \
- xmlparse.cc qif.cc report.cc transform.cc csv.cc derive.cc \
- emacs.cc reconcile.cc $(am__append_3) $(am__append_5) \
- $(am__append_7) $(am__append_9)
+libledger_la_SOURCES = amount.cc times.cc quotes.cc balance.cc \
+ value.cc xml.cc xpath.cc mask.cc format.cc util.cc session.cc \
+ journal.cc parser.cc textual.cc binary.cc xmlparse.cc qif.cc \
+ report.cc transform.cc csv.cc derive.cc emacs.cc reconcile.cc \
+ $(am__append_3) $(am__append_5) $(am__append_7) \
+ $(am__append_9)
libledger_la_LDFLAGS = -release 3.0
libpyledger_la_CXXFLAGS = -DUSE_BOOST_PYTHON=1 $(am__append_11)
libpyledger_la_SOURCES = \
@@ -356,10 +356,10 @@ libpyledger_la_SOURCES = \
libpyledger_la_LDFLAGS = -release 3.0
pkginclude_HEADERS = \
amount.h \
+ times.h \
balance.h \
binary.h \
csv.h \
- datetime.h \
debug.h \
derive.h \
emacs.h \
@@ -399,8 +399,8 @@ ledger_LDADD = $(LIBOBJS) libledger.la gdtoa/libgdtoa.la \
ledger_LDFLAGS = -static # for the sake of command-line speed
info_TEXINFOS = ledger.texi
@HAVE_BOOST_PYTHON_TRUE@ledger_so_SOURCES = pyledger.cc
-@HAVE_BOOST_PYTHON_TRUE@PYLIBS = pyledger ledger gdtoa boost_python \
-@HAVE_BOOST_PYTHON_TRUE@ gmp pcre $(am__append_18) \
+@HAVE_BOOST_PYTHON_TRUE@PYLIBS = pyledger ledger gdtoa boost_date_time \
+@HAVE_BOOST_PYTHON_TRUE@ boost_python gmp pcre $(am__append_18) \
@HAVE_BOOST_PYTHON_TRUE@ $(am__append_19) $(am__append_20)
@DEBUG_FALSE@@HAVE_BOOST_PYTHON_TRUE@DEBUG_LEVEL = 0
@DEBUG_TRUE@@HAVE_BOOST_PYTHON_TRUE@DEBUG_LEVEL = 4
@@ -569,7 +569,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-balance.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-binary.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-csv.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-datetime.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-debug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-derive.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-emacs.Plo@am__quote@
@@ -585,6 +584,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-report.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-session.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-textual.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-times.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-trace.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-transform.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-util.Plo@am__quote@
@@ -624,6 +624,13 @@ libledger_la-amount.lo: amount.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -c -o libledger_la-amount.lo `test -f 'amount.cc' || echo '$(srcdir)/'`amount.cc
+libledger_la-times.lo: times.cc
+@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -MT libledger_la-times.lo -MD -MP -MF $(DEPDIR)/libledger_la-times.Tpo -c -o libledger_la-times.lo `test -f 'times.cc' || echo '$(srcdir)/'`times.cc
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-times.Tpo $(DEPDIR)/libledger_la-times.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='times.cc' object='libledger_la-times.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -c -o libledger_la-times.lo `test -f 'times.cc' || echo '$(srcdir)/'`times.cc
+
libledger_la-quotes.lo: quotes.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -MT libledger_la-quotes.lo -MD -MP -MF $(DEPDIR)/libledger_la-quotes.Tpo -c -o libledger_la-quotes.lo `test -f 'quotes.cc' || echo '$(srcdir)/'`quotes.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-quotes.Tpo $(DEPDIR)/libledger_la-quotes.Plo
@@ -645,13 +652,6 @@ libledger_la-value.lo: value.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -c -o libledger_la-value.lo `test -f 'value.cc' || echo '$(srcdir)/'`value.cc
-libledger_la-datetime.lo: datetime.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -MT libledger_la-datetime.lo -MD -MP -MF $(DEPDIR)/libledger_la-datetime.Tpo -c -o libledger_la-datetime.lo `test -f 'datetime.cc' || echo '$(srcdir)/'`datetime.cc
-@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-datetime.Tpo $(DEPDIR)/libledger_la-datetime.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='datetime.cc' object='libledger_la-datetime.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -c -o libledger_la-datetime.lo `test -f 'datetime.cc' || echo '$(srcdir)/'`datetime.cc
-
libledger_la-xml.lo: xml.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -MT libledger_la-xml.lo -MD -MP -MF $(DEPDIR)/libledger_la-xml.Tpo -c -o libledger_la-xml.lo `test -f 'xml.cc' || echo '$(srcdir)/'`xml.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-xml.Tpo $(DEPDIR)/libledger_la-xml.Plo
diff --git a/acconf.h.in b/acconf.h.in
index 6e7c03d3..e1f233dd 100644
--- a/acconf.h.in
+++ b/acconf.h.in
@@ -33,18 +33,12 @@
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
-/* Define to 1 if you have the `strftime' function. */
-#undef HAVE_STRFTIME
-
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
-/* Define to 1 if you have the `strptime' function. */
-#undef HAVE_STRPTIME
-
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
diff --git a/amount.cc b/amount.cc
index a971ebe3..7b294026 100644
--- a/amount.cc
+++ b/amount.cc
@@ -210,18 +210,6 @@ static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec)
mpz_tdiv_q(out, out, divisor);
}
-amount_t::amount_t(const bool val)
-{
- TRACE_CTOR("amount_t(const bool)");
- if (val) {
- quantity = &true_value;
- quantity->ref++;
- } else {
- quantity = NULL;
- }
- commodity_ = NULL;
-}
-
amount_t::amount_t(const long val)
{
TRACE_CTOR("amount_t(const long)");
@@ -419,21 +407,6 @@ amount_t& amount_t::operator=(const amount_t& amt)
return *this;
}
-amount_t& amount_t::operator=(const bool val)
-{
- if (! val) {
- if (quantity)
- _clear();
- } else {
- commodity_ = NULL;
- if (quantity)
- _release();
- quantity = &true_value;
- quantity->ref++;
- }
- return *this;
-}
-
amount_t& amount_t::operator=(const long val)
{
if (val == 0) {
@@ -774,12 +747,12 @@ amount_t::operator double() const
return std::atof(num.str().c_str());
}
-amount_t amount_t::value(const datetime_t& moment) const
+amount_t amount_t::value(const ptime& moment) const
{
if (quantity) {
amount_t amt(commodity().value(moment));
if (! amt.realzero())
- return (amt * *this).round();
+ return (amt * number()).round();
}
return *this;
}
@@ -1159,7 +1132,7 @@ static void parse_commodity(std::istream& in, std::string& symbol)
}
bool parse_annotations(std::istream& in, amount_t& price,
- datetime_t& date, std::string& tag)
+ ptime& date, std::string& tag)
{
bool has_date = false;
@@ -1189,7 +1162,7 @@ bool parse_annotations(std::istream& in, amount_t& price,
price = price.round(); // no need to retain individual precision
}
else if (c == '[') {
- if (date)
+ if (date.is_not_a_date_time())
throw new amount_error("Commodity specifies more than one date");
in.get(c);
@@ -1199,7 +1172,7 @@ bool parse_annotations(std::istream& in, amount_t& price,
else
throw new amount_error("Commodity date lacks closing bracket");
- date = buf;
+ date = ptime_from_local_date_string(buf);
has_date = true;
}
else if (c == '(') {
@@ -1239,7 +1212,7 @@ void amount_t::parse(std::istream& in, unsigned char flags)
std::string symbol;
std::string quant;
amount_t tprice;
- datetime_t tdate;
+ ptime tdate;
bool had_date = false;
std::string tag;
unsigned int comm_flags = COMMODITY_STYLE_DEFAULTS;
@@ -1579,7 +1552,7 @@ bool amount_t::valid() const
}
void amount_t::annotate_commodity(const amount_t& tprice,
- const datetime_t& tdate,
+ const ptime& tdate,
const std::string& tag)
{
const commodity_t * this_base;
@@ -1602,7 +1575,7 @@ void amount_t::annotate_commodity(const amount_t& tprice,
commodity_t * ann_comm =
annotated_commodity_t::find_or_create
(*this_base, ! tprice && this_ann ? this_ann->price : tprice,
- ! tdate && this_ann ? this_ann->date : tdate,
+ tdate.is_not_a_date_time() && this_ann ? this_ann->date : tdate,
tag.empty() && this_ann ? this_ann->tag : tag);
if (ann_comm)
set_commodity(*ann_comm);
@@ -1631,12 +1604,12 @@ amount_t amount_t::strip_annotations(const bool _keep_price,
commodity_t * new_comm;
if ((_keep_price && ann_comm.price) ||
- (_keep_date && ann_comm.date) ||
- (_keep_tag && ! ann_comm.tag.empty()))
+ (_keep_date && ! ann_comm.date.is_not_a_date_time()) ||
+ (_keep_tag && ! ann_comm.tag.empty()))
{
new_comm = annotated_commodity_t::find_or_create
(*ann_comm.ptr, _keep_price ? ann_comm.price : amount_t(),
- _keep_date ? ann_comm.date : datetime_t(),
+ _keep_date ? ann_comm.date : ptime(),
_keep_tag ? ann_comm.tag : "");
} else {
new_comm = commodity_t::find_or_create(ann_comm.base_symbol());
@@ -1662,7 +1635,7 @@ amount_t amount_t::price() const
return *this;
}
-datetime_t amount_t::date() const
+ptime amount_t::date() const
{
if (commodity_ && commodity_->annotated) {
DEBUG_PRINT("amounts.commodities",
@@ -1670,11 +1643,11 @@ datetime_t amount_t::date() const
<< ((annotated_commodity_t *)commodity_)->date);
return ((annotated_commodity_t *)commodity_)->date;
}
- return 0L;
+ return ptime();
}
-void commodity_base_t::add_price(const datetime_t& date,
+void commodity_base_t::add_price(const ptime& date,
const amount_t& price)
{
if (! history)
@@ -1690,7 +1663,7 @@ void commodity_base_t::add_price(const datetime_t& date,
}
}
-bool commodity_base_t::remove_price(const datetime_t& date)
+bool commodity_base_t::remove_price(const ptime& date)
{
if (history) {
history_map::size_type n = history->prices.erase(date);
@@ -1800,15 +1773,15 @@ commodity_t * commodity_t::find(const std::string& symbol)
return NULL;
}
-amount_t commodity_base_t::value(const datetime_t& moment)
+amount_t commodity_base_t::value(const ptime& moment)
{
- datetime_t age;
+ ptime age;
amount_t price;
if (history) {
assert(history->prices.size() > 0);
- if (! moment) {
+ if (moment.is_not_a_date_time()) {
history_map::reverse_iterator r = history->prices.rbegin();
age = (*r).first;
price = (*r).second;
@@ -1826,7 +1799,7 @@ amount_t commodity_base_t::value(const datetime_t& moment)
age = (*i).first;
price = (*i).second;
} else {
- age = 0;
+ age = ptime();
}
} else {
price = (*i).second;
@@ -1838,7 +1811,7 @@ amount_t commodity_base_t::value(const datetime_t& moment)
if (updater && ! (flags & COMMODITY_STYLE_NOMARKET))
(*updater)(*this, moment, age,
(history && history->prices.size() > 0 ?
- (*history->prices.rbegin()).first : datetime_t()), price);
+ (*history->prices.rbegin()).first : ptime()), price);
return price;
}
@@ -1854,7 +1827,7 @@ bool annotated_commodity_t::operator==(const commodity_t& comm) const
price != static_cast<const annotated_commodity_t&>(comm).price))
return false;
- if (date &&
+ if (! date.is_not_a_date_time() &&
(! comm.annotated ||
date != static_cast<const annotated_commodity_t&>(comm).date))
return false;
@@ -1870,13 +1843,13 @@ bool annotated_commodity_t::operator==(const commodity_t& comm) const
void
annotated_commodity_t::write_annotations(std::ostream& out,
const amount_t& price,
- const datetime_t& date,
+ const ptime& date,
const std::string& tag)
{
if (price)
out << " {" << price << '}';
- if (date)
+ if (! date.is_not_a_date_time())
out << " [" << date << ']';
if (! tag.empty())
@@ -1886,7 +1859,7 @@ annotated_commodity_t::write_annotations(std::ostream& out,
commodity_t *
annotated_commodity_t::create(const commodity_t& comm,
const amount_t& price,
- const datetime_t& date,
+ const ptime& date,
const std::string& tag,
const std::string& mapping_key)
{
@@ -1927,7 +1900,7 @@ annotated_commodity_t::create(const commodity_t& comm,
namespace {
std::string make_qualified_name(const commodity_t& comm,
const amount_t& price,
- const datetime_t& date,
+ const ptime& date,
const std::string& tag)
{
if (price < 0)
@@ -1953,7 +1926,7 @@ namespace {
commodity_t *
annotated_commodity_t::find_or_create(const commodity_t& comm,
const amount_t& price,
- const datetime_t& date,
+ const ptime& date,
const std::string& tag)
{
std::string name = make_qualified_name(comm, price, date, tag);
@@ -2016,15 +1989,17 @@ bool compare_amount_commodities::operator()(const amount_t * left,
}
}
- if (! aleftcomm.date && arightcomm.date)
+ if (aleftcomm.date.is_not_a_date_time() &&
+ ! arightcomm.date.is_not_a_date_time())
return true;
- if (aleftcomm.date && ! arightcomm.date)
+ if (! aleftcomm.date.is_not_a_date_time() &&
+ arightcomm.date.is_not_a_date_time())
return false;
- if (aleftcomm.date && arightcomm.date) {
- int diff = aleftcomm.date - arightcomm.date;
- if (diff)
- return diff < 0;
+ if (! aleftcomm.date.is_not_a_date_time() &&
+ ! arightcomm.date.is_not_a_date_time()) {
+ time_duration diff = aleftcomm.date - arightcomm.date;
+ return diff.is_negative();
}
if (aleftcomm.tag.empty() && ! arightcomm.tag.empty())
diff --git a/amount.h b/amount.h
index 3786dde0..c6160c93 100644
--- a/amount.h
+++ b/amount.h
@@ -42,13 +42,13 @@
#include <cassert>
#include <exception>
-#include "datetime.h"
+#include "times.h"
#include "debug.h"
#include "error.h"
namespace ledger {
-extern bool do_cleanup;
+extern bool do_cleanup;
class commodity_t;
@@ -94,7 +94,6 @@ class amount_t
TRACE_CTOR("amount_t(const char *)");
parse(val);
}
- amount_t(const bool val);
amount_t(const long val);
amount_t(const unsigned long val);
amount_t(const double val);
@@ -118,7 +117,7 @@ class amount_t
commodity_ = &comm;
}
void annotate_commodity(const amount_t& price,
- const datetime_t& date = datetime_t(),
+ const ptime& date = ptime(),
const std::string& tag = "");
amount_t strip_annotations(const bool _keep_price = keep_price,
const bool _keep_date = keep_date,
@@ -127,7 +126,7 @@ class amount_t
commodity_ = NULL;
}
amount_t price() const;
- datetime_t date() const;
+ ptime date() const;
bool null() const {
return ! quantity && ! has_commodity();
@@ -137,7 +136,6 @@ class amount_t
amount_t& operator=(const amount_t& amt);
amount_t& operator=(const std::string& val);
amount_t& operator=(const char * val);
- amount_t& operator=(const bool val);
amount_t& operator=(const long val);
amount_t& operator=(const unsigned long val);
amount_t& operator=(const double val);
@@ -299,7 +297,7 @@ class amount_t
return ! (*this == num);
}
- amount_t value(const datetime_t& moment) const;
+ amount_t value(const ptime& moment) const;
// jww (2007-04-17): change the name here
void abs() {
@@ -327,7 +325,7 @@ class amount_t
char * item_pool_end);
friend bool parse_annotations(std::istream& in, amount_t& price,
- datetime_t& date, std::string& tag);
+ ptime& date, std::string& tag);
// Streaming interface
@@ -387,63 +385,50 @@ inline amount_t abs(const amount_t& amt) {
return amt < 0 ? amt.negated() : amt;
}
-template <typename T>
-inline amount_t operator+(const T val, const amount_t& amt) {
- amount_t temp(val);
- temp += amt;
- return temp;
-}
-
-template <typename T>
-inline amount_t operator-(const T val, const amount_t& amt) {
- amount_t temp(val);
- temp -= amt;
- return temp;
+#define DEFINE_AMOUNT_OPERATORS(T) \
+inline amount_t operator+(const T val, const amount_t& amt) { \
+ amount_t temp(val); \
+ temp += amt; \
+ return temp; \
+} \
+inline amount_t operator-(const T val, const amount_t& amt) { \
+ amount_t temp(val); \
+ temp -= amt; \
+ return temp; \
+} \
+inline amount_t operator*(const T val, const amount_t& amt) { \
+ amount_t temp(val); \
+ temp *= amt; \
+ return temp; \
+} \
+inline amount_t operator/(const T val, const amount_t& amt) { \
+ amount_t temp(val); \
+ temp /= amt; \
+ return temp; \
+} \
+ \
+inline bool operator<(const T val, const amount_t& amt) { \
+ return amount_t(val) < amt; \
+} \
+inline bool operator<=(const T val, const amount_t& amt) { \
+ return amount_t(val) <= amt; \
+} \
+inline bool operator>(const T val, const amount_t& amt) { \
+ return amount_t(val) > amt; \
+} \
+inline bool operator>=(const T val, const amount_t& amt) { \
+ return amount_t(val) >= amt; \
+} \
+inline bool operator==(const T val, const amount_t& amt) { \
+ return amount_t(val) == amt; \
+} \
+inline bool operator!=(const T val, const amount_t& amt) { \
+ return amount_t(val) != amt; \
}
-template <typename T>
-inline amount_t operator*(const T val, const amount_t& amt) {
- amount_t temp(val);
- temp *= amt;
- return temp;
-}
-
-template <typename T>
-inline amount_t operator/(const T val, const amount_t& amt) {
- amount_t temp(val);
- temp /= amt;
- return temp;
-}
-
-template <typename T>
-inline bool operator<(const T val, const amount_t& amt) {
- return amount_t(val) < amt;
-}
-
-template <typename T>
-inline bool operator<=(const T val, const amount_t& amt) {
- return amount_t(val) <= amt;
-}
-
-template <typename T>
-inline bool operator>(const T val, const amount_t& amt) {
- return amount_t(val) > amt;
-}
-
-template <typename T>
-inline bool operator>=(const T val, const amount_t& amt) {
- return amount_t(val) >= amt;
-}
-
-template <typename T>
-inline bool operator==(const T val, const amount_t& amt) {
- return amount_t(val) == amt;
-}
-
-template <typename T>
-inline bool operator!=(const T val, const amount_t& amt) {
- return amount_t(val) != amt;
-}
+DEFINE_AMOUNT_OPERATORS(long)
+DEFINE_AMOUNT_OPERATORS(unsigned long)
+DEFINE_AMOUNT_OPERATORS(double)
inline std::ostream& operator<<(std::ostream& out, const amount_t& amt) {
amt.print(out, false, amount_t::full_strings);
@@ -463,8 +448,8 @@ inline std::istream& operator>>(std::istream& in, amount_t& amt) {
#define COMMODITY_STYLE_NOMARKET 0x0010
#define COMMODITY_STYLE_BUILTIN 0x0020
-typedef std::map<const datetime_t, amount_t> history_map;
-typedef std::pair<const datetime_t, amount_t> history_pair;
+typedef std::map<const ptime, amount_t> history_map;
+typedef std::pair<const ptime, amount_t> history_pair;
class commodity_base_t;
@@ -510,23 +495,24 @@ class commodity_base_t
struct history_t {
history_map prices;
- datetime_t last_lookup;
- datetime_t bogus_time;
- history_t() : last_lookup(0), bogus_time(0) {}
+ ptime last_lookup;
+ // jww (2007-04-18): What is bogus_time?
+ ptime bogus_time;
+ history_t() : last_lookup(), bogus_time() {}
};
history_t * history;
- void add_price(const datetime_t& date, const amount_t& price);
- bool remove_price(const datetime_t& date);
- amount_t value(const datetime_t& moment = datetime_t::now);
+ void add_price(const ptime& date, const amount_t& price);
+ bool remove_price(const ptime& date);
+ amount_t value(const ptime& moment = now);
class updater_t {
public:
virtual ~updater_t() {}
virtual void operator()(commodity_base_t& commodity,
- const datetime_t& moment,
- const datetime_t& date,
- const datetime_t& last,
+ const ptime& moment,
+ const ptime& date,
+ const ptime& last,
amount_t& price) = 0;
};
friend class updater_t;
@@ -657,13 +643,13 @@ class commodity_t
return base->history;
}
- void add_price(const datetime_t& date, const amount_t& price) {
+ void add_price(const ptime& date, const amount_t& price) {
return base->add_price(date, price);
}
- bool remove_price(const datetime_t& date) {
+ bool remove_price(const ptime& date) {
return base->remove_price(date);
}
- amount_t value(const datetime_t& moment = datetime_t::now) const {
+ amount_t value(const ptime& moment = now) const {
return base->value(moment);
}
@@ -676,7 +662,7 @@ class annotated_commodity_t : public commodity_t
const commodity_t * ptr;
amount_t price;
- datetime_t date;
+ ptime date;
std::string tag;
explicit annotated_commodity_t() {
@@ -692,19 +678,19 @@ class annotated_commodity_t : public commodity_t
static void write_annotations(std::ostream& out,
const amount_t& price,
- const datetime_t& date,
+ const ptime& date,
const std::string& tag);
private:
static commodity_t * create(const commodity_t& comm,
const amount_t& price,
- const datetime_t& date,
+ const ptime& date,
const std::string& tag,
const std::string& mapping_key);
static commodity_t * find_or_create(const commodity_t& comm,
const amount_t& price,
- const datetime_t& date,
+ const ptime& date,
const std::string& tag);
friend class amount_t;
diff --git a/balance.cc b/balance.cc
index 3422a4e7..3d31bc5d 100644
--- a/balance.cc
+++ b/balance.cc
@@ -33,7 +33,7 @@ amount_t balance_t::amount(const commodity_t& commodity) const
return amount_t();
}
-balance_t balance_t::value(const datetime_t& moment) const
+balance_t balance_t::value(const ptime& moment) const
{
balance_t temp;
@@ -57,20 +57,19 @@ balance_t balance_t::price() const
return temp;
}
-datetime_t balance_t::date() const
+ptime balance_t::date() const
{
- datetime_t temp;
+ ptime temp;
for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end();
i++) {
- datetime_t tdate = (*i).second.date();
- if (! temp && tdate)
+ ptime tdate = (*i).second.date();
+ if (temp.is_not_a_date_time() && ! tdate.is_not_a_date_time())
temp = tdate;
else if (temp != tdate)
- return datetime_t();
+ return ptime();
}
-
return temp;
}
diff --git a/balance.h b/balance.h
index e98ebbdc..d50cfa78 100644
--- a/balance.h
+++ b/balance.h
@@ -430,9 +430,9 @@ class balance_t
amount_t amount(const commodity_t& commodity =
*commodity_t::null_commodity) const;
- balance_t value(const datetime_t& moment = datetime_t::now) const;
+ balance_t value(const ptime& moment = now) const;
balance_t price() const;
- datetime_t date() const;
+ ptime date() const;
balance_t
strip_annotations(const bool keep_price = amount_t::keep_price,
@@ -880,13 +880,13 @@ class balance_pair_t
*commodity_t::null_commodity) const {
return quantity.amount(commodity);
}
- balance_t value(const datetime_t& moment = datetime_t::now) const {
+ balance_t value(const ptime& moment = now) const {
return quantity.value(moment);
}
balance_t price() const {
return quantity.price();
}
- datetime_t date() const {
+ ptime date() const {
return quantity.date();
}
diff --git a/binary.cc b/binary.cc
index 9ac40bdb..4fff40ba 100644
--- a/binary.cc
+++ b/binary.cc
@@ -135,7 +135,7 @@ inline void read_binary_value(char *& data, value_t& val)
read_binary_long(data, *((long *) val.data));
break;
case value_t::DATETIME:
- read_binary_number(data, *((datetime_t *) val.data));
+ read_binary_number(data, *((ptime *) val.data));
break;
case value_t::AMOUNT:
read_binary_amount(data, *((amount_t *) val.data));
@@ -281,7 +281,7 @@ inline void read_binary_commodity_base_extra(char *& data,
for (unsigned long i = 0, count = read_binary_long<unsigned long>(data);
i < count;
i++) {
- datetime_t when;
+ ptime when;
read_binary_number(data, when);
amount_t amt;
read_binary_amount(data, amt);
@@ -661,7 +661,7 @@ void write_binary_value(std::ostream& out, const value_t& val)
write_binary_long(out, *((long *) val.data));
break;
case value_t::DATETIME:
- write_binary_number(out, *((datetime_t *) val.data));
+ write_binary_number(out, *((ptime *) val.data));
break;
case value_t::AMOUNT:
write_binary_amount(out, *((amount_t *) val.data));
diff --git a/configure b/configure
index 955dd116..68e439e5 100755
--- a/configure
+++ b/configure
@@ -875,10 +875,6 @@ LIBTOOL
EMACS
EMACSLOADPATH
lispdir
-HAVE_GMP_TRUE
-HAVE_GMP_FALSE
-HAVE_PCRE_TRUE
-HAVE_PCRE_FALSE
USE_XML_TRUE
USE_XML_FALSE
HAVE_EXPAT_TRUE
@@ -4852,7 +4848,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 4855 "configure"' > conftest.$ac_ext
+ echo '#line 4851 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -7111,11 +7107,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7114: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7110: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7118: \$? = $ac_status" >&5
+ echo "$as_me:7114: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7379,11 +7375,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7382: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7378: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7386: \$? = $ac_status" >&5
+ echo "$as_me:7382: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7483,11 +7479,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7486: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7482: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:7490: \$? = $ac_status" >&5
+ echo "$as_me:7486: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -9791,7 +9787,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 9794 "configure"
+#line 9790 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -9891,7 +9887,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 9894 "configure"
+#line 9890 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12227,11 +12223,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12230: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:12226: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:12234: \$? = $ac_status" >&5
+ echo "$as_me:12230: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -12331,11 +12327,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12334: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:12330: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:12338: \$? = $ac_status" >&5
+ echo "$as_me:12334: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -13901,11 +13897,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13904: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13900: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:13908: \$? = $ac_status" >&5
+ echo "$as_me:13904: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -14005,11 +14001,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14008: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:14004: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:14012: \$? = $ac_status" >&5
+ echo "$as_me:14008: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -16203,11 +16199,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16206: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16202: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16210: \$? = $ac_status" >&5
+ echo "$as_me:16206: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -16471,11 +16467,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16474: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16470: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16478: \$? = $ac_status" >&5
+ echo "$as_me:16474: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -16575,11 +16571,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16578: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16574: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:16582: \$? = $ac_status" >&5
+ echo "$as_me:16578: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -19503,14 +19499,6 @@ fi
echo "${ECHO_T}$libgmp_avail" >&6; }
if test x$libgmp_avail = xtrue ; then
- if true; then
- HAVE_GMP_TRUE=
- HAVE_GMP_FALSE='#'
-else
- HAVE_GMP_TRUE='#'
- HAVE_GMP_FALSE=
-fi
-
LIBS="-lgmp $LIBS"
else
{ { echo "$as_me:$LINENO: error: \"Could not find gmp library (set CPPFLAGS and LDFLAGS?)\"
@@ -19589,14 +19577,6 @@ fi
echo "${ECHO_T}$libpcre_avail" >&6; }
if test x$libpcre_avail = xtrue ; then
- if true; then
- HAVE_PCRE_TRUE=
- HAVE_PCRE_FALSE='#'
-else
- HAVE_PCRE_TRUE='#'
- HAVE_PCRE_FALSE=
-fi
-
LIBS="-lpcre $LIBS"
else
{ { echo "$as_me:$LINENO: error: \"Could not find pcre library (set CPPFLAGS and LDFLAGS?)\"
@@ -19606,6 +19586,102 @@ See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
+# check for Boost date_time
+{ echo "$as_me:$LINENO: checking if boost_date_time is available" >&5
+echo $ECHO_N "checking if boost_date_time is available... $ECHO_C" >&6; }
+if test "${boost_date_time_cpplib_avail+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ boost_date_time_save_libs=$LIBS
+ LIBS="-lboost_date_time $LIBS"
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <boost/date_time/posix_time/posix_time.hpp>
+ #include <boost/date_time/gregorian/gregorian.hpp>
+ #include <boost/date_time/local_time_adjustor.hpp>
+ #include <boost/date_time/time_duration.hpp>
+
+ using namespace boost::posix_time;
+ using namespace boost::date_time;
+
+ #include <ctime>
+
+ inline ptime time_to_system_local(const ptime& when) {
+ struct std::tm tm_gmt = to_tm(when);
+ return from_time_t(mktime(&tm_gmt));
+ }
+int
+main ()
+{
+ptime t10 = ptime(boost::gregorian::from_string("2007-01-15"),
+ ptime::time_duration_type());
+
+ ptime t12 = time_to_system_local(t10);
+
+ return t10 != t12;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ boost_date_time_cpplib_avail=true
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ boost_date_time_cpplib_avail=false
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ LIBS=$boost_date_time_save_libs
+fi
+{ echo "$as_me:$LINENO: result: $boost_date_time_cpplib_avail" >&5
+echo "${ECHO_T}$boost_date_time_cpplib_avail" >&6; }
+
+if test x$boost_date_time_cpplib_avail = xtrue ; then
+ LIBS="-lboost_date_time $LIBS"
+else
+ { { echo "$as_me:$LINENO: error: \"Could not find boost_date_time library (set CPPFLAGS and LDFLAGS?)\"
+See \`config.log' for more details." >&5
+echo "$as_me: error: \"Could not find boost_date_time library (set CPPFLAGS and LDFLAGS?)\"
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
# check for expat or xmlparse
# Check whether --enable-xml was given.
if test "${enable_xml+set}" = set; then
@@ -19620,6 +19696,7 @@ else
xml=true
fi
+
if test x$xml = xtrue; then
USE_XML_TRUE=
USE_XML_FALSE='#'
@@ -19860,6 +19937,7 @@ else
ofx=true
fi
+
if test x$ofx = xtrue; then
USE_OFX_TRUE=
USE_OFX_FALSE='#'
@@ -19982,6 +20060,7 @@ else
python=false
fi
+
if test x$python = xtrue; then
USE_PYTHON_TRUE=
USE_PYTHON_FALSE='#'
@@ -20248,6 +20327,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
fi
{ echo "$as_me:$LINENO: result: $boost_python_cpplib_avail" >&5
echo "${ECHO_T}$boost_python_cpplib_avail" >&6; }
+
if test x$boost_python_cpplib_avail = xtrue ; then
if true; then
HAVE_BOOST_PYTHON_TRUE=
@@ -20303,6 +20383,7 @@ else
debug=false
fi
+
if test x$debug = xtrue; then
DEBUG_TRUE=
DEBUG_FALSE='#'
@@ -21126,9 +21207,7 @@ fi
-
-
-for ac_func in access mktime realpath strftime strptime getpwuid getpwnam
+for ac_func in access mktime realpath getpwuid getpwnam
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -21341,20 +21420,6 @@ echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
-if test -z "${HAVE_GMP_TRUE}" && test -z "${HAVE_GMP_FALSE}"; then
- { { echo "$as_me:$LINENO: error: conditional \"HAVE_GMP\" was never defined.
-Usually this means the macro was only invoked conditionally." >&5
-echo "$as_me: error: conditional \"HAVE_GMP\" was never defined.
-Usually this means the macro was only invoked conditionally." >&2;}
- { (exit 1); exit 1; }; }
-fi
-if test -z "${HAVE_PCRE_TRUE}" && test -z "${HAVE_PCRE_FALSE}"; then
- { { echo "$as_me:$LINENO: error: conditional \"HAVE_PCRE\" was never defined.
-Usually this means the macro was only invoked conditionally." >&5
-echo "$as_me: error: conditional \"HAVE_PCRE\" was never defined.
-Usually this means the macro was only invoked conditionally." >&2;}
- { (exit 1); exit 1; }; }
-fi
if test -z "${USE_XML_TRUE}" && test -z "${USE_XML_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"USE_XML\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
@@ -22159,10 +22224,6 @@ LIBTOOL!$LIBTOOL$ac_delim
EMACS!$EMACS$ac_delim
EMACSLOADPATH!$EMACSLOADPATH$ac_delim
lispdir!$lispdir$ac_delim
-HAVE_GMP_TRUE!$HAVE_GMP_TRUE$ac_delim
-HAVE_GMP_FALSE!$HAVE_GMP_FALSE$ac_delim
-HAVE_PCRE_TRUE!$HAVE_PCRE_TRUE$ac_delim
-HAVE_PCRE_FALSE!$HAVE_PCRE_FALSE$ac_delim
USE_XML_TRUE!$USE_XML_TRUE$ac_delim
USE_XML_FALSE!$USE_XML_FALSE$ac_delim
HAVE_EXPAT_TRUE!$HAVE_EXPAT_TRUE$ac_delim
@@ -22192,7 +22253,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 39; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 35; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.in b/configure.in
index 0c6e249a..f4f1e9b7 100644
--- a/configure.in
+++ b/configure.in
@@ -77,7 +77,6 @@ AC_CACHE_CHECK(
LIBS=$libgmp_save_libs])
if [test x$libgmp_avail = xtrue ]; then
- AM_CONDITIONAL(HAVE_GMP, true)
LIBS="-lgmp $LIBS"
else
AC_MSG_FAILURE("Could not find gmp library (set CPPFLAGS and LDFLAGS?)")
@@ -99,12 +98,50 @@ AC_CACHE_CHECK(
LIBS=$libpcre_save_libs])
if [test x$libpcre_avail = xtrue ]; then
- AM_CONDITIONAL(HAVE_PCRE, true)
LIBS="-lpcre $LIBS"
else
AC_MSG_FAILURE("Could not find pcre library (set CPPFLAGS and LDFLAGS?)")
fi
+# check for Boost date_time
+AC_CACHE_CHECK(
+ [if boost_date_time is available],
+ [boost_date_time_cpplib_avail],
+ [boost_date_time_save_libs=$LIBS
+ LIBS="-lboost_date_time $LIBS"
+ AC_LANG_PUSH(C++)
+ AC_TRY_LINK(
+ [#include <boost/date_time/posix_time/posix_time.hpp>
+ #include <boost/date_time/gregorian/gregorian.hpp>
+ #include <boost/date_time/local_time_adjustor.hpp>
+ #include <boost/date_time/time_duration.hpp>
+
+ using namespace boost::posix_time;
+ using namespace boost::date_time;
+
+ #include <ctime>
+
+ inline ptime time_to_system_local(const ptime& when) {
+ struct std::tm tm_gmt = to_tm(when);
+ return from_time_t(mktime(&tm_gmt));
+ }],
+ [ptime t10 = ptime(boost::gregorian::from_string("2007-01-15"),
+ ptime::time_duration_type());
+
+ ptime t12 = time_to_system_local(t10);
+
+ return t10 != t12;],
+ [boost_date_time_cpplib_avail=true],
+ [boost_date_time_cpplib_avail=false])
+ AC_LANG_POP
+ LIBS=$boost_date_time_save_libs])
+
+if [test x$boost_date_time_cpplib_avail = xtrue ]; then
+ LIBS="-lboost_date_time $LIBS"
+else
+ AC_MSG_FAILURE("Could not find boost_date_time library (set CPPFLAGS and LDFLAGS?)")
+fi
+
# check for expat or xmlparse
AC_ARG_ENABLE(xml,
[ --enable-xml Turn on support for XML parsing],
@@ -113,6 +150,7 @@ AC_ARG_ENABLE(xml,
no) xml=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-xml) ;;
esac],[xml=true])
+
AM_CONDITIONAL(USE_XML, test x$xml = xtrue)
if [test x$xml = xtrue ]; then
@@ -185,6 +223,7 @@ AC_ARG_ENABLE(ofx,
no) ofx=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-ofx) ;;
esac],[ofx=true])
+
AM_CONDITIONAL(USE_OFX, test x$ofx = xtrue)
if [test x$ofx = xtrue ]; then
@@ -220,6 +259,7 @@ AC_ARG_ENABLE(python,
no) python=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-python) ;;
esac],[python=false])
+
AM_CONDITIONAL(USE_PYTHON, test x$python = xtrue)
if [test x$python = xtrue ]; then
@@ -243,6 +283,7 @@ if [test x$python = xtrue ]; then
[boost_python_cpplib_avail=false])
AC_LANG_POP
LIBS=$boost_python_save_libs])
+
if [test x$boost_python_cpplib_avail = xtrue ]; then
AM_CONDITIONAL(HAVE_BOOST_PYTHON, true)
LIBS="-lboost_python -lpython$PYTHON_VERSION $LIBS"
@@ -264,6 +305,7 @@ AC_ARG_ENABLE(debug,
no) debug=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
esac],[debug=false])
+
AM_CONDITIONAL(DEBUG, test x$debug = xtrue)
# Checks for header files.
@@ -278,7 +320,7 @@ AC_STRUCT_TM
# Checks for library functions.
#AC_FUNC_ERROR_AT_LINE
AC_HEADER_STDC
-AC_CHECK_FUNCS([access mktime realpath strftime strptime getpwuid getpwnam])
+AC_CHECK_FUNCS([access mktime realpath getpwuid getpwnam])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
diff --git a/datetime.cc b/datetime.cc
deleted file mode 100644
index 1038b87d..00000000
--- a/datetime.cc
+++ /dev/null
@@ -1,575 +0,0 @@
-#if defined(__GNUG__) && __GNUG__ < 3
-#define _XOPEN_SOURCE
-#endif
-
-#include "datetime.h"
-#include "util.h"
-
-#include <ctime>
-#include <cctype>
-
-date_t date_t::now(std::time(NULL));
-int date_t::current_year = date_t::now.year();
-std::string date_t::input_format;
-std::string date_t::output_format = "%Y/%m/%d";
-
-const char * date_t::formats[] = {
- "%Y/%m/%d",
- "%m/%d",
- "%Y.%m.%d",
- "%m.%d",
- "%Y-%m-%d",
- "%m-%d",
- "%a",
- "%A",
- "%b",
- "%B",
- "%Y",
- NULL
-};
-
-datetime_t datetime_t::now(std::time(NULL));
-
-namespace {
-#if 0
- static std::time_t base = -1;
- static int base_year = -1;
-#endif
-
- static const int month_days[12] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
-
- bool parse_date_mask(const char * date_str, struct std::tm * result)
- {
- if (! date_t::input_format.empty()) {
- std::memset(result, INT_MAX, sizeof(struct std::tm));
- if (strptime(date_str, date_t::input_format.c_str(), result))
- return true;
- }
- for (const char ** f = date_t::formats; *f; f++) {
- std::memset(result, INT_MAX, sizeof(struct std::tm));
- if (strptime(date_str, *f, result))
- return true;
- }
- return false;
- }
-
- bool parse_date(const char * date_str, std::time_t * result, const int year)
- {
- struct std::tm when;
-
- if (! parse_date_mask(date_str, &when))
- return false;
-
- when.tm_hour = 0;
- when.tm_min = 0;
- when.tm_sec = 0;
-
- if (when.tm_year == -1)
- when.tm_year = ((year == -1) ? date_t::current_year : (year - 1900));
-
- if (when.tm_mon == -1)
- when.tm_mon = 0;
-
- if (when.tm_mday == -1)
- when.tm_mday = 1;
-
- *result = std::mktime(&when);
-
- return true;
- }
-
- inline bool quick_parse_date(const char * date_str, std::time_t * result)
- {
- return parse_date(date_str, result, date_t::current_year + 1900);
- }
-}
-
-date_t::date_t(const std::string& _when)
-{
- if (! quick_parse_date(_when.c_str(), &when))
- throw new date_error
- (std::string("Invalid date string: ") + _when);
-}
-
-void date_t::parse(std::istream& in)
-{
- char buf[256];
- char c = peek_next_nonws(in);
- READ_INTO(in, buf, 255, c,
- std::isalnum(c) || c == '-' || c == '.' || c == '/');
-
- if (! quick_parse_date(buf, &when))
- throw new date_error
- (std::string("Invalid date string: ") + buf);
-}
-
-datetime_t::datetime_t(const std::string& _when)
-{
- std::istringstream datestr(_when);
- parse(datestr); // parse both the date and optional time
-}
-
-void datetime_t::parse(std::istream& in)
-{
- date_t::parse(in); // first grab the date part
-
- istream_pos_type beg_pos = in.tellg();
-
- int thour = 0;
- int tmin = 0;
- int tsec = 0;
-
- // Now look for the (optional) time specifier. If no time is given,
- // we use midnight of the given day.
- char buf[256];
- char c = peek_next_nonws(in);
- if (! std::isdigit(c))
- goto abort;
- READ_INTO(in, buf, 255, c, std::isdigit(c));
- if (buf[0] == '\0')
- goto abort;
-
- thour = std::atoi(buf);
- if (thour > 23)
- goto abort;
-
- if (in.peek() == ':') {
- in.get(c);
- READ_INTO(in, buf, 255, c, std::isdigit(c));
- if (buf[0] == '\0')
- goto abort;
-
- tmin = std::atoi(buf);
- if (tmin > 59)
- goto abort;
-
- if (in.peek() == ':') {
- in.get(c);
- READ_INTO(in, buf, 255, c, std::isdigit(c));
- if (buf[0] == '\0')
- goto abort;
-
- tsec = std::atoi(buf);
- if (tsec > 59)
- goto abort;
- }
- }
-
- c = peek_next_nonws(in);
- if (c == 'a' || c == 'p' || c == 'A' || c == 'P') {
- if (thour > 12)
- goto abort;
- in.get(c);
-
- if (c == 'p' || c == 'P') {
- if (thour != 12)
- thour += 12;
- } else {
- if (thour == 12)
- thour = 0;
- }
-
- c = in.peek();
- if (c == 'm' || c == 'M')
- in.get(c);
- }
-
- struct std::tm * desc = std::localtime(&when);
-
- desc->tm_hour = thour;
- desc->tm_min = tmin;
- desc->tm_sec = tsec;
- desc->tm_isdst = -1;
-
- when = std::mktime(desc);
-
- return; // the time has been successfully parsed
-
- abort: // there was no valid time string to parse
- in.clear();
- in.seekg(beg_pos, std::ios::beg);
-}
-
-std::ostream& operator<<(std::ostream& out, const datetime_t& moment)
-{
- std::string format = datetime_t::output_format;
- std::tm * when = moment.localtime();
- if (when->tm_hour != 0 || when->tm_min != 0 || when->tm_sec != 0)
- format += " %H:%M:%S";
-
- char buf[64];
- std::strftime(buf, 63, format.c_str(), when);
- out << buf;
- return out;
-}
-
-datetime_t interval_t::first(const datetime_t& moment) const
-{
- datetime_t quant(begin);
-
- if (moment && moment > quant) {
- // Find an efficient starting point for the upcoming while loop.
- // We want 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 time.
-
- struct std::tm * desc = std::localtime(&moment.when);
-
- if (years)
- desc->tm_mon = 0;
- desc->tm_mday = 1;
-
- desc->tm_hour = 0;
- desc->tm_min = 0;
- desc->tm_sec = 0;
- desc->tm_isdst = -1;
-
- quant = std::mktime(desc);
-
- datetime_t temp;
- while (moment >= (temp = increment(quant))) {
- if (quant == temp)
- break;
- quant = temp;
- }
- }
-
- return quant;
-}
-
-datetime_t interval_t::increment(const datetime_t& moment) const
-{
- struct std::tm * desc = std::localtime(&moment.when);
-
- if (years)
- desc->tm_year += years;
- if (months)
- desc->tm_mon += months;
- if (days)
- desc->tm_mon += days;
-
- desc->tm_hour += hours;
- desc->tm_min += minutes;
- desc->tm_sec += seconds;
-
- desc->tm_isdst = -1;
-
- return std::mktime(desc);
-}
-
-namespace {
- void parse_inclusion_specifier(const std::string& word,
- datetime_t * begin, datetime_t * end)
- {
- struct std::tm when;
-
- if (! parse_date_mask(word.c_str(), &when))
- throw new datetime_error(std::string("Could not parse date mask: ") + word);
-
- when.tm_hour = 0;
- when.tm_min = 0;
- when.tm_sec = 0;
- when.tm_isdst = -1;
-
- bool saw_year = true;
- bool saw_mon = true;
- bool saw_day = true;
-
- if (when.tm_year == -1) {
- when.tm_year = date_t::current_year;
- saw_year = false;
- }
- if (when.tm_mon == -1) {
- when.tm_mon = 0;
- saw_mon = false;
- } else {
- saw_year = false; // don't increment by year if month used
- }
- if (when.tm_mday == -1) {
- when.tm_mday = 1;
- saw_day = false;
- } else {
- saw_mon = false; // don't increment by month if day used
- saw_year = false; // don't increment by year if day used
- }
-
- if (begin) {
- *begin = std::mktime(&when);
- if (end)
- *end = interval_t(saw_day ? 86400 : 0, saw_mon ? 1 : 0,
- saw_year ? 1 : 0).increment(*begin);
- }
- else if (end) {
- *end = std::mktime(&when);
- }
- }
-
- inline void read_lower_word(std::istream& in, std::string& word) {
- in >> word;
- for (int i = 0, l = word.length(); i < l; i++)
- word[i] = std::tolower(word[i]);
- }
-
- void parse_date_words(std::istream& in, std::string& word,
- datetime_t * begin, datetime_t * end)
- {
- std::string type;
-
- bool mon_spec = false;
- char buf[32];
-
- if (word == "this" || word == "last" || word == "next") {
- type = word;
- if (! in.eof())
- read_lower_word(in, word);
- else
- word = "month";
- } else {
- type = "this";
- }
-
- if (word == "month") {
- std::strftime(buf, 31, "%B", datetime_t::now.localtime());
- word = buf;
- mon_spec = true;
- }
- else if (word == "year") {
- std::strftime(buf, 31, "%Y", datetime_t::now.localtime());
- word = buf;
- }
-
- parse_inclusion_specifier(word, begin, end);
-
- if (type == "last") {
- if (mon_spec) {
- if (begin)
- *begin = interval_t(0, -1, 0).increment(*begin);
- if (end)
- *end = interval_t(0, -1, 0).increment(*end);
- } else {
- if (begin)
- *begin = interval_t(0, 0, -1).increment(*begin);
- if (end)
- *end = interval_t(0, 0, -1).increment(*end);
- }
- }
- else if (type == "next") {
- if (mon_spec) {
- if (begin)
- *begin = interval_t(0, 1, 0).increment(*begin);
- if (end)
- *end = interval_t(0, 1, 0).increment(*end);
- } else {
- if (begin)
- *begin = interval_t(0, 0, 1).increment(*begin);
- if (end)
- *end = interval_t(0, 0, 1).increment(*end);
- }
- }
- }
-}
-
-void interval_t::parse(std::istream& in)
-{
- std::string word;
-
- while (! in.eof()) {
- read_lower_word(in, word);
- if (word == "every") {
- read_lower_word(in, word);
- if (std::isdigit(word[0])) {
- int quantity = std::atol(word.c_str());
- read_lower_word(in, word);
- if (word == "days")
- days = quantity;
- else if (word == "weeks")
- days = 7 * quantity;
- else if (word == "months")
- months = quantity;
- else if (word == "quarters")
- 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;
- else if (word == "week")
- days = 7;
- else if (word == "month")
- months = 1;
- else if (word == "quarter")
- 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;
- else if (word == "weekly")
- days = 7;
- else if (word == "biweekly")
- days = 14;
- else if (word == "monthly")
- months = 1;
- else if (word == "bimonthly")
- months = 2;
- else if (word == "quarterly")
- 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);
- }
- else if (word == "in") {
- read_lower_word(in, word);
- parse_date_words(in, word, &begin, &end);
- }
- else if (word == "from" || word == "since") {
- read_lower_word(in, word);
- parse_date_words(in, word, &begin, NULL);
- }
- else if (word == "to" || word == "until") {
- read_lower_word(in, word);
- parse_date_words(in, word, NULL, &end);
- }
- else {
- parse_inclusion_specifier(word, &begin, &end);
- }
- }
-}
-
-#if 0
-#ifdef USE_BOOST_PYTHON
-
-#include <boost/python.hpp>
-
-using namespace boost::python;
-
-unsigned int interval_len(interval_t& interval)
-{
- int periods = 1;
- std::time_t when = interval.first();
- while (interval.end && when < interval.end) {
- when = interval.increment(when);
- if (when < interval.end)
- periods++;
- }
- return periods;
-}
-
-std::time_t interval_getitem(interval_t& interval, int i)
-{
- static std::time_t last_index = 0;
- static std::time_t last_moment = 0;
-
- if (i == 0) {
- last_index = 0;
- last_moment = interval.first();
- }
- else {
- last_moment = interval.increment(last_moment);
- if (interval.end && last_moment >= interval.end) {
- PyErr_SetString(PyExc_IndexError, "Index out of range");
- throw_error_already_set();
- }
- }
- return last_moment;
-}
-
-std::time_t py_parse_date(const char * date_str)
-{
- std::time_t temp;
- if (parse_date(date_str, &temp))
- return temp;
- return 0;
-}
-
-std::time_t py_parse_date_yr(const char * date_str, const int year)
-{
- std::time_t temp;
- if (parse_date(date_str, &temp, year))
- return temp;
- return 0;
-}
-
-void export_datetime()
-{
- class_< date_t > ("Date")
- .def("now", &date_t::now)
- .def("formats", &date_t::formats)
- .def("current_year", &date_t::current_year)
- .def("input_format", &date_t::input_format)
- .def("output_format", &date_t::output_format)
-
- .def(init<>())
- .def(init<const date_t&>())
- .def(init<const std::time_t&>())
- .def(init<const interval_t&>())
- .def(init<const std::string&>())
-
- .def(self += other<const interval_t&>())
- .def(self -= other<const date_t&>())
- .def(self += long())
- .def(self -= long())
-
- .def(self < other<const date_t&>())
- .def(self <= other<const date_t&>())
- .def(self > other<const date_t&>())
- .def(self >= other<const date_t&>())
- .def(self == other<const date_t&>())
- .def(self != other<const date_t&>())
-
- .def("year", &date_t::year)
- .def("month", &date_t::month)
- .def("day", &date_t::day)
- .def("wday", &date_t::wday)
- .def("localtime", &date_t::localtime)
-
- .def("write", &date_t::write)
- .def("parse", &date_t::parse)
- ;
-
- class_< interval_t >
- ("Interval", init<optional<int, int, int, std::time_t, std::time_t> >())
- .def(init<std::string>())
- .def(! self)
-
- .def_readwrite("years", &interval_t::years)
- .def_readwrite("months", &interval_t::months)
- .def_readwrite("days", &interval_t::days)
- .def_readwrite("hours", &interval_t::hours)
- .def_readwrite("minutes", &interval_t::minutes)
- .def_readwrite("seconds", &interval_t::seconds)
-
- .def_readwrite("begin", &interval_t::begin)
- .def_readwrite("end", &interval_t::end)
-
- .def("__len__", interval_len)
- .def("__getitem__", interval_getitem)
-
- .def("start", &interval_t::start)
- .def("first", &interval_t::first)
- .def("increment", &interval_t::increment)
- ;
-
- def("parse_date", py_parse_date);
- def("parse_date", py_parse_date_yr);
-}
-
-#endif // USE_BOOST_PYTHON
-#endif
diff --git a/datetime.h b/datetime.h
deleted file mode 100644
index cd7b3a16..00000000
--- a/datetime.h
+++ /dev/null
@@ -1,320 +0,0 @@
-#ifndef _DATETIME_H
-#define _DATETIME_H
-
-#include <ctime>
-#include <sstream>
-
-#include "error.h"
-
-class date_error : public error {
- public:
- date_error(const std::string& _reason) throw() : error(_reason) {}
- virtual ~date_error() throw() {}
-};
-
-struct interval_t;
-class datetime_t;
-
-class date_t
-{
- date_t(const datetime_t& _when);
-
- protected:
- std::time_t when;
-
- public:
- static date_t now;
- static const char * formats[];
- static int current_year;
- static std::string input_format;
- static std::string output_format;
-
- date_t() : when(0) {}
- date_t(const date_t& _when) : when(_when.when) {}
-
- date_t(const std::time_t _when) : when(_when) {
-#if 0
- struct std::tm * moment = std::localtime(&_when);
- moment->tm_hour = 0;
- moment->tm_min = 0;
- moment->tm_sec = 0;
- when = std::mktime(moment);
-#endif
- }
- date_t(const interval_t& period);
- date_t(const std::string& _when);
-
- virtual ~date_t() {}
-
- date_t& operator=(const date_t& _when) {
- when = _when.when;
- return *this;
- }
- date_t& operator=(const std::time_t _when) {
- return *this = date_t(_when);
- }
- date_t& operator=(const datetime_t& _when) {
- return *this = date_t(_when);
- }
- date_t& operator=(const interval_t& period) {
- return *this = date_t(period);
- }
- date_t& operator=(const std::string& _when) {
- return *this = date_t(_when);
- }
-
- date_t& operator+=(const interval_t& period);
-
- long operator-=(const date_t& date) {
- return (when - date.when) / 86400;
- }
-
- virtual date_t& operator+=(const long days) {
- // jww (2006-03-26): This is not accurate enough when DST is in effect!
- when += days * 86400;
- return *this;
- }
- virtual date_t& operator-=(const long days) {
- // jww (2006-03-26): This is not accurate enough when DST is in effect!
- when -= days * 86400;
- return *this;
- }
-
-#define DEF_DATE_OP(OP) \
- bool operator OP(const date_t& other) const { \
- return when OP other.when; \
- }
-
- DEF_DATE_OP(<)
- DEF_DATE_OP(<=)
- DEF_DATE_OP(>)
- DEF_DATE_OP(>=)
- DEF_DATE_OP(==)
- DEF_DATE_OP(!=)
-
- operator bool() const {
- return when != 0;
- }
- operator std::time_t() const {
- return when;
- }
- operator std::string() const {
- return to_string();
- }
-
- std::string to_string(const std::string& format = output_format) const {
- char buf[64];
- std::strftime(buf, 63, format.c_str(), localtime());
- return buf;
- }
-
- int year() const {
- return localtime()->tm_year + 1900;
- }
- int month() const {
- return localtime()->tm_mon + 1;
- }
- int day() const {
- return localtime()->tm_mday;
- }
- int wday() const {
- return localtime()->tm_wday;
- }
-
- std::tm * localtime() const {
- return std::localtime(&when);
- }
-
- void write(std::ostream& out,
- const std::string& format = output_format) const {
- out << to_string(format);
- }
-
- void parse(std::istream& in);
-
- friend class datetime_t;
- friend struct interval_t;
-};
-
-inline long operator-(const date_t& left, const date_t& right) {
- date_t temp(left);
- temp -= right;
- return temp;
-}
-
-inline date_t operator+(const date_t& left, const long days) {
- date_t temp(left);
- temp += days;
- return temp;
-}
-
-inline date_t operator-(const date_t& left, const long days) {
- date_t temp(left);
- temp -= days;
- return temp;
-}
-
-inline std::ostream& operator<<(std::ostream& out, const date_t& moment) {
- moment.write(out);
- return out;
-}
-
-inline std::istream& operator>>(std::istream& in, date_t& moment) {
- moment.parse(in);
- return in;
-}
-
-class datetime_error : public error {
- public:
- datetime_error(const std::string& _reason) throw() : error(_reason) {}
- virtual ~datetime_error() throw() {}
-};
-
-class datetime_t : public date_t
-{
- public:
- static datetime_t now;
-
- datetime_t() : date_t(now.when) {}
- datetime_t(const datetime_t& _when) : date_t(_when.when) {}
- datetime_t(const date_t& _when) : date_t(_when) {}
-
- datetime_t(const std::time_t _when) : date_t(_when) {}
- datetime_t(const std::string& _when);
-
- datetime_t& operator=(const datetime_t& _when) {
- when = _when.when;
- return *this;
- }
- datetime_t& operator=(const date_t& _when) {
- when = _when.when;
- return *this;
- }
- datetime_t& operator=(const std::time_t _when) {
- return *this = datetime_t(_when);
- }
- datetime_t& operator=(const std::string& _when) {
- return *this = datetime_t(_when);
- }
-
- long operator-=(const datetime_t& date) {
- return when - date.when;
- }
-
- virtual datetime_t& operator+=(const long secs) {
- when += secs;
- return *this;
- }
- virtual datetime_t& operator-=(const long secs) {
- when -= secs;
- return *this;
- }
-
-#define DEF_DATETIME_OP(OP) \
- bool operator OP(const datetime_t& other) const { \
- return when OP other.when; \
- }
-
- DEF_DATETIME_OP(<)
- DEF_DATETIME_OP(<=)
- DEF_DATETIME_OP(>)
- DEF_DATETIME_OP(>=)
- DEF_DATETIME_OP(==)
- DEF_DATETIME_OP(!=)
-
- int hour() const {
- return localtime()->tm_hour;
- }
- int min() const {
- return localtime()->tm_min;
- }
- int sec() const {
- return localtime()->tm_sec;
- }
-
- void parse(std::istream& in);
-};
-
-inline long operator-(const datetime_t& left, const datetime_t& right) {
- std::time_t left_time(left);
- std::time_t right_time(right);
- return left_time - right_time;
-}
-
-inline datetime_t operator+(const datetime_t& left, const long seconds) {
- datetime_t temp(left);
- temp += seconds;
- return temp;
-}
-
-inline datetime_t operator-(const datetime_t& left, const long seconds) {
- datetime_t temp(left);
- temp -= seconds;
- return temp;
-}
-
-std::ostream& operator<<(std::ostream& out, const datetime_t& moment);
-
-inline std::istream& operator>>(std::istream& in, datetime_t& moment) {
- moment.parse(in);
- return in;
-}
-
-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;
-
- interval_t(int _days = 0, int _months = 0, int _years = 0,
- 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) {}
-
- interval_t(const std::string& desc)
- : years(0), months(0), days(0),
- hours(0), minutes(0), seconds(0) {
- std::istringstream stream(desc);
- parse(stream);
- }
-
- operator bool() const {
- return (years > 0 || months > 0 || days > 0 ||
- hours > 0 || minutes > 0 || seconds > 0);
- }
-
- void start(const datetime_t& moment) {
- begin = first(moment);
- }
- datetime_t first(const datetime_t& moment = datetime_t()) const;
- datetime_t increment(const datetime_t&) const;
-
- void parse(std::istream& in);
-};
-
-inline date_t::date_t(const interval_t& period) {
- when = period.first().when;
-}
-
-inline date_t& date_t::operator+=(const interval_t& period) {
- return *this = period.increment(*this);
-}
-
-inline date_t::date_t(const datetime_t& _when) {
- assert(0);
- struct std::tm * moment = _when.localtime();
- moment->tm_hour = 0;
- moment->tm_min = 0;
- moment->tm_sec = 0;
- when = std::mktime(moment);
-}
-
-#endif // _DATETIME_H
diff --git a/debug.h b/debug.h
index 50f94775..ae4c52c1 100644
--- a/debug.h
+++ b/debug.h
@@ -63,8 +63,6 @@ void debug_assert(const std::string& reason,
#include <iostream>
#include <cstdlib>
-#include "datetime.h"
-
#define DEBUG_ENABLED
extern std::ostream * _debug_stream;
diff --git a/derive.cc b/derive.cc
index 3d35522e..71203bd3 100644
--- a/derive.cc
+++ b/derive.cc
@@ -1,5 +1,4 @@
#include "derive.h"
-#include "datetime.h"
#include "error.h"
#include "mask.h"
diff --git a/gnucash.cc b/gnucash.cc
index 9089638f..11053927 100644
--- a/gnucash.cc
+++ b/gnucash.cc
@@ -318,7 +318,7 @@ unsigned int gnucash_parser_t::parse(std::istream& in,
// user specified.
//
// jww (2006-09-13): Make this parser local somehow.
- date_t::input_format = "%Y-%m-%d %H:%M:%S %z";
+ //date_t::input_format = "%Y-%m-%d %H:%M:%S %z";
count = 0;
action = NO_ACTION;
diff --git a/journal.cc b/journal.cc
index a64b005e..eaf3de35 100644
--- a/journal.cc
+++ b/journal.cc
@@ -1,5 +1,4 @@
#include "journal.h"
-#include "datetime.h"
#include "mask.h"
#include "format.h"
#if 0
@@ -23,14 +22,14 @@ transaction_t::~transaction_t()
if (cost) delete cost;
}
-datetime_t transaction_t::actual_date() const
+ptime transaction_t::actual_date() const
{
if (! _date && entry)
return entry->actual_date();
return _date;
}
-datetime_t transaction_t::effective_date() const
+ptime transaction_t::effective_date() const
{
if (! _date_eff && entry)
return entry->effective_date();
@@ -182,7 +181,7 @@ bool entry_base_t::finalize()
! (*x)->amount.commodity().annotated)
(*x)->amount.annotate_commodity
(abs(per_unit_cost),
- entry ? entry->actual_date() : datetime_t(),
+ entry ? entry->actual_date() : ptime(),
entry ? entry->code : "");
(*x)->cost = new amount_t(- (per_unit_cost * (*x)->amount));
diff --git a/journal.h b/journal.h
index fee2b2d5..5506421d 100644
--- a/journal.h
+++ b/journal.h
@@ -23,8 +23,8 @@ class transaction_t
enum state_t { UNCLEARED, CLEARED, PENDING };
entry_t * entry;
- datetime_t _date;
- datetime_t _date_eff;
+ ptime _date;
+ ptime _date_eff;
account_t * account;
amount_t amount;
std::string amount_expr;
@@ -67,9 +67,9 @@ class transaction_t
}
~transaction_t();
- datetime_t actual_date() const;
- datetime_t effective_date() const;
- datetime_t date() const {
+ ptime actual_date() const;
+ ptime effective_date() const;
+ ptime date() const {
if (use_effective_date)
return effective_date();
else
@@ -151,8 +151,8 @@ class entry_base_t
class entry_t : public entry_base_t
{
public:
- datetime_t _date;
- datetime_t _date_eff;
+ ptime _date;
+ ptime _date_eff;
std::string code;
std::string payee;
@@ -167,15 +167,15 @@ class entry_t : public entry_base_t
TRACE_DTOR("entry_t");
}
- datetime_t actual_date() const {
+ ptime actual_date() const {
return _date;
}
- datetime_t effective_date() const {
- if (! _date_eff)
+ ptime effective_date() const {
+ if (_date_eff.is_not_a_date_time())
return _date;
return _date_eff;
}
- datetime_t date() const {
+ ptime date() const {
if (transaction_t::use_effective_date)
return effective_date();
else
diff --git a/ledger.h b/ledger.h
index c186e19e..39e78021 100644
--- a/ledger.h
+++ b/ledger.h
@@ -13,7 +13,6 @@
#include <amount.h>
#include <balance.h>
#include <value.h>
-#include <datetime.h>
#include <xml.h>
#include <xpath.h>
#include <format.h>
diff --git a/ofx.cc b/ofx.cc
index 5f0ab6f4..57e39d49 100644
--- a/ofx.cc
+++ b/ofx.cc
@@ -1,7 +1,6 @@
#include "journal.h"
#include "ofx.h"
#include "format.h"
-#include "datetime.h"
#include "error.h"
#include "debug.h"
#include "util.h"
diff --git a/py_amount.cc b/py_amount.cc
index 18fd3588..afa5b963 100644
--- a/py_amount.cc
+++ b/py_amount.cc
@@ -34,9 +34,9 @@ struct commodity_updater_wrap : public commodity_base_t::updater_t
commodity_updater_wrap(PyObject * self_) : self(self_) {}
virtual void operator()(commodity_base_t& commodity,
- const datetime_t& moment,
- const datetime_t& date,
- const datetime_t& last,
+ const ptime& moment,
+ const ptime& date,
+ const ptime& last,
amount_t& price) {
call_method<void>(self, "__call__", commodity, moment, date, last, price);
}
diff --git a/py_eval.cc b/py_eval.cc
index 72522a2f..95b104d5 100644
--- a/py_eval.cc
+++ b/py_eval.cc
@@ -8,7 +8,6 @@ void export_amount();
#if 0
void export_balance();
void export_value();
-void export_datetime();
void export_journal();
void export_parser();
@@ -29,7 +28,6 @@ void initialize_ledger_for_python()
#if 0
export_balance();
export_value();
- export_datetime();
export_journal();
export_parser();
diff --git a/qif.cc b/qif.cc
index a8a8595f..5e7e06eb 100644
--- a/qif.cc
+++ b/qif.cc
@@ -1,6 +1,5 @@
#include "journal.h"
#include "qif.h"
-#include "datetime.h"
#include "error.h"
#include "util.h"
diff --git a/quotes.cc b/quotes.cc
index c5af712b..af4e09b7 100644
--- a/quotes.cc
+++ b/quotes.cc
@@ -1,5 +1,4 @@
#include "quotes.h"
-#include "datetime.h"
#include "error.h"
#include "debug.h"
@@ -10,15 +9,15 @@
namespace ledger {
void quotes_by_script::operator()(commodity_base_t& commodity,
- const datetime_t& moment,
- const datetime_t& date,
- const datetime_t& last,
+ const ptime& moment,
+ const ptime& date,
+ const ptime& last,
amount_t& price)
{
DEBUG_CLASS("ledger.quotes.download");
DEBUG_PRINT_("commodity: " << commodity.symbol);
- DEBUG_PRINT_TIME_(datetime_t::now);
+ DEBUG_PRINT_TIME_(now);
DEBUG_PRINT_TIME_(moment);
DEBUG_PRINT_TIME_(date);
DEBUG_PRINT_TIME_(last);
@@ -27,9 +26,9 @@ void quotes_by_script::operator()(commodity_base_t& commodity,
DEBUG_PRINT_("pricing_leeway is " << pricing_leeway);
if ((commodity.history &&
- (datetime_t::now - commodity.history->last_lookup) < (long)pricing_leeway) ||
- (datetime_t::now - last) < (long)pricing_leeway ||
- (price && moment > date && (moment - date) <= (long)pricing_leeway))
+ (now - commodity.history->last_lookup) < pricing_leeway) ||
+ (now - last) < pricing_leeway ||
+ (price && moment > date && (moment - date) <= pricing_leeway))
return;
using namespace std;
@@ -58,9 +57,9 @@ void quotes_by_script::operator()(commodity_base_t& commodity,
DEBUG_PRINT_("downloaded quote: " << buf);
price.parse(buf);
- commodity.add_price(datetime_t::now, price);
+ commodity.add_price(now, price);
- commodity.history->last_lookup = datetime_t::now;
+ commodity.history->last_lookup = now;
cache_dirty = true;
if (price && ! price_db.empty()) {
@@ -69,8 +68,12 @@ void quotes_by_script::operator()(commodity_base_t& commodity,
#else
ofstream database(price_db.c_str(), ios_base::out | ios_base::app);
#endif
- database << "P " << datetime_t::now.to_string("%Y/%m/%d %H:%M:%S")
+#if 0
+ // jww (2007-04-18): Need to convert to local time and print
+ // here, print with UTC timezone specifier
+ database << "P " << now.to_string("%Y/%m/%d %H:%M:%S")
<< " " << commodity.symbol << " " << price << endl;
+#endif
}
} else {
throw new error(std::string("Failed to download price for '") +
diff --git a/quotes.h b/quotes.h
index 12164b14..43062a26 100644
--- a/quotes.h
+++ b/quotes.h
@@ -8,20 +8,20 @@ namespace ledger {
class quotes_by_script : public commodity_base_t::updater_t
{
std::string price_db;
- unsigned long pricing_leeway;
+ time_duration pricing_leeway;
bool& cache_dirty;
public:
quotes_by_script(std::string _price_db,
- unsigned long _pricing_leeway,
+ time_duration _pricing_leeway,
bool& _cache_dirty)
: price_db(_price_db), pricing_leeway(_pricing_leeway),
cache_dirty(_cache_dirty) {}
virtual void operator()(commodity_base_t& commodity,
- const datetime_t& moment,
- const datetime_t& date,
- const datetime_t& last,
+ const ptime& moment,
+ const ptime& date,
+ const ptime& last,
amount_t& price);
};
diff --git a/report.cc b/report.cc
index 45902460..5ff2a5fd 100644
--- a/report.cc
+++ b/report.cc
@@ -44,13 +44,13 @@ void report_t::ftime(value_t& result, xml::xpath_t::scope_t * locals)
if (locals->args.size() < 1)
throw new error("usage: ftime(DATE [, DATE_FORMAT])");
- datetime_t date = locals->args[0].to_datetime();
+ ptime date = locals->args[0].to_datetime();
std::string date_format;
if (locals->args.size() == 2)
date_format = locals->args[1].to_string();
else
- date_format = datetime_t::output_format;
+ date_format = ptime::output_format;
result.set_string(date.to_string(date_format));
}
diff --git a/session.cc b/session.cc
index 5bb17c23..49b12f72 100644
--- a/session.cc
+++ b/session.cc
@@ -136,7 +136,7 @@ bool session_t::resolve(const std::string& name, value_t& result,
switch (*p) {
case 'd':
if (name == "date_format") {
- result.set_string(datetime_t::output_format);
+ result.set_string(ptime::output_format);
return true;
}
break;
diff --git a/session.h b/session.h
index 16c57d1c..de7044e7 100644
--- a/session.h
+++ b/session.h
@@ -37,7 +37,7 @@ class session_t : public xml::xpath_t::scope_t
bool verbose_mode;
bool trace_mode;
- datetime_t now;
+ ptime now;
elision_style_t elision_style;
@@ -90,7 +90,7 @@ class session_t : public xml::xpath_t::scope_t
verbose_mode(false),
trace_mode(false),
- now(datetime_t::now),
+ now(now),
elision_style(ABBREVIATE),
abbrev_length(2),
diff --git a/tests/corelib/numerics/Commodity.cc b/tests/corelib/numerics/Commodity.cc
index 77cdd7b9..b15211f6 100644
--- a/tests/corelib/numerics/Commodity.cc
+++ b/tests/corelib/numerics/Commodity.cc
@@ -15,10 +15,23 @@ void CommodityTestCase::testConstructors()
void CommodityTestCase::testPriceHistory()
{
+ datetime_t jan17_07("2007/01/17 00:00:00");
+ datetime_t feb27_07("2007/02/27 18:00:00");
+ datetime_t feb28_07("2007/02/28 06:00:00");
+ datetime_t feb28_07sbm("2007/02/28 11:59:59");
+ datetime_t mar01_07("2007/03/01 00:00:00");
+ datetime_t apr15_07("2007/04/15 13:00:00");
+
// jww (2007-04-17): tbd
amount_t x1("100.10 AAPL");
- assertEqual(x1, x1.value(datetime_t()));
+ // Commodities cannot be constructed by themselves, since a great
+ // deal of their state depends on how they were seen to be used.
+ commodity_t& aapl(x1.commodity());
+
+ aapl.add_price(datetime_t(), amount_t("$10.20"));
+
+ assertEqual(amount_t("$1021.02"), x1.value(datetime_t()));
assertValid(x1);
}
diff --git a/textual.cc b/textual.cc
index c98164a6..fa923d20 100644
--- a/textual.cc
+++ b/textual.cc
@@ -30,7 +30,7 @@ static std::list<std::pair<std::string, int> > include_stack;
#ifdef TIMELOG_SUPPORT
struct time_entry_t {
- datetime_t checkin;
+ ptime checkin;
account_t * account;
std::string desc;
};
@@ -491,7 +491,7 @@ bool textual_parser_t::test(std::istream& in) const
return true;
}
-static void clock_out_from_timelog(const datetime_t& when,
+static void clock_out_from_timelog(const ptime& when,
account_t * account,
const char * desc,
journal_t * journal)
@@ -674,16 +674,17 @@ unsigned int textual_parser_t::parse(std::istream& in,
if (! time_field_ptr) break;
std::string date_field = date_field_ptr;
- char * symbol_and_price;
- datetime_t datetime;
+ char * symbol_and_price;
+ ptime datetime;
if (std::isdigit(time_field_ptr[0])) {
symbol_and_price = next_element(time_field_ptr);
if (! symbol_and_price) break;
- datetime = date_field + " " + time_field_ptr;
+ datetime = ptime_from_local_time_string(date_field + " " +
+ time_field_ptr);
} else {
symbol_and_price = time_field_ptr;
- datetime = date_t(date_field);
+ datetime = ptime_from_local_date_string(date_field);
}
std::string symbol;
@@ -706,7 +707,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
}
case 'Y': // set current year
- date_t::current_year = std::atoi(skip_ws(line + 1)) - 1900;
+ date_t::current_year = std::atoi(skip_ws(line + 1));
break;
#ifdef TIMELOG_SUPPORT
@@ -879,7 +880,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
for (std::list<time_entry_t>::iterator i = time_entries.begin();
i != time_entries.end();
i++)
- clock_out_from_timelog(datetime_t::now, (*i).account, NULL, journal);
+ clock_out_from_timelog(now, (*i).account, NULL, journal);
time_entries.clear();
}
diff --git a/times.cc b/times.cc
new file mode 100644
index 00000000..60926112
--- /dev/null
+++ b/times.cc
@@ -0,0 +1,7 @@
+#include "times.h"
+
+namespace ledger {
+
+ ptime now = boost::posix_time::second_clock::universal_time();
+
+}
diff --git a/times.h b/times.h
new file mode 100644
index 00000000..953d3d4d
--- /dev/null
+++ b/times.h
@@ -0,0 +1,41 @@
+#ifndef _TIMES_H
+#define _TIMES_H
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/date_time/posix_time/posix_time_duration.hpp>
+#include <boost/date_time/posix_time/posix_time_config.hpp>
+#include <boost/date_time/local_time_adjustor.hpp>
+
+#include <ctime>
+#include <string>
+
+namespace ledger {
+
+using namespace boost::posix_time;
+using namespace boost::date_time;
+
+typedef ptime::time_duration_type time_duration;
+
+class interval_t {};
+
+inline ptime ptime_local_to_utc(const ptime& when) {
+ struct std::tm tm_gmt = to_tm(when);
+ return from_time_t(std::mktime(&tm_gmt));
+}
+
+// jww (2007-04-18): I need to make a general parsing function
+// instead, and then make these into private methods.
+inline ptime ptime_from_local_date_string(const std::string& date_string) {
+ return ptime_local_to_utc(ptime(boost::gregorian::from_string(date_string),
+ time_duration()));
+}
+
+inline ptime ptime_from_local_time_string(const std::string& time_string) {
+ return ptime_local_to_utc(time_from_string(time_string));
+}
+
+extern ptime now;
+
+}
+
+#endif /* _TIMES_H */
diff --git a/trace.cc b/trace.cc
index e82b5a5e..45f33c77 100644
--- a/trace.cc
+++ b/trace.cc
@@ -8,8 +8,8 @@ bool trace_mode;
void trace(const std::string& cat, const std::string& str)
{
char buf[32];
- std::strftime(buf, 31, "%H:%M:%S", datetime_t::now.localtime());
- std::cerr << buf << " " << cat << ": " << str << std::endl;
+ std::cerr << now.to_short_string() << " " << cat << ": " << str
+ << std::endl;
}
void trace_push(const std::string& cat, const std::string& str,
diff --git a/value.cc b/value.cc
index 0e3389e4..5eab7aee 100644
--- a/value.cc
+++ b/value.cc
@@ -27,14 +27,14 @@ long value_t::to_integer() const
}
}
-datetime_t value_t::to_datetime() const
+ptime value_t::to_datetime() const
{
if (type == DATETIME) {
- return *(datetime_t *) data;
+ return *(ptime *) data;
} else {
value_t temp(*this);
temp.cast(DATETIME);
- return *(datetime_t *) temp.data;
+ return *(ptime *) temp.data;
}
}
@@ -171,7 +171,7 @@ value_t& value_t::operator=(const value_t& val)
return *this;
}
else if (type == DATETIME && val.type == DATETIME) {
- *((datetime_t *) data) = *((datetime_t *) val.data);
+ *((ptime *) data) = *((ptime *) val.data);
return *this;
}
else if (type == AMOUNT && val.type == AMOUNT) {
@@ -207,7 +207,7 @@ value_t& value_t::operator=(const value_t& val)
break;
case DATETIME:
- *((datetime_t *) data) = *((datetime_t *) val.data);
+ *((ptime *) data) = *((ptime *) val.data);
break;
case AMOUNT:
@@ -293,16 +293,16 @@ value_t& value_t::operator+=(const value_t& val)
case DATETIME:
switch (val.type) {
case INTEGER:
- *((datetime_t *) data) += *((long *) val.data);
+ *((ptime *) data) += seconds(*((long *) val.data));
break;
case AMOUNT:
- *((datetime_t *) data) += long(*((amount_t *) val.data));
+ *((ptime *) data) += seconds(long(*((amount_t *) val.data)));
break;
case BALANCE:
- *((datetime_t *) data) += long(*((balance_t *) val.data));
+ *((ptime *) data) += seconds(long(*((balance_t *) val.data)));
break;
case BALANCE_PAIR:
- *((datetime_t *) data) += long(*((balance_pair_t *) val.data));
+ *((ptime *) data) += seconds(long(*((balance_pair_t *) val.data)));
break;
case STRING:
throw new value_error("Cannot add a string to an date/time");
@@ -476,22 +476,22 @@ value_t& value_t::operator-=(const value_t& val)
case DATETIME:
switch (val.type) {
case INTEGER:
- *((datetime_t *) data) -= *((long *) val.data);
+ *((ptime *) data) -= seconds(*((long *) val.data));
break;
case DATETIME: {
- long tval = *((datetime_t *) data) - *((datetime_t *) val.data);
+ time_duration tval = ((ptime *) data)->operator-(*((ptime *) val.data));
cast(INTEGER);
- *((long *) data) = tval;
+ *((long *) data) = tval.total_seconds();
break;
}
case AMOUNT:
- *((datetime_t *) data) -= long(*((amount_t *) val.data));
+ *((ptime *) data) -= seconds(long(*((amount_t *) val.data)));
break;
case BALANCE:
- *((datetime_t *) data) -= long(*((balance_t *) val.data));
+ *((ptime *) data) -= seconds(long(*((balance_t *) val.data)));
break;
case BALANCE_PAIR:
- *((datetime_t *) data) -= long(*((balance_pair_t *) val.data));
+ *((ptime *) data) -= seconds(long(*((balance_pair_t *) val.data)));
break;
default:
assert(0);
@@ -877,7 +877,7 @@ value_t::operator bool() const
case INTEGER:
return *(long *) data;
case DATETIME:
- return *(datetime_t *) data;
+ return ! ((ptime *) data)->is_not_a_date_time();
case AMOUNT:
return *(amount_t *) data;
case BALANCE:
@@ -911,7 +911,7 @@ value_t::operator long() const
case INTEGER:
return *((long *) data);
case DATETIME:
- return *((datetime_t *) data);
+ throw new value_error("Cannot convert a date/time to an integer");
case AMOUNT:
return *((amount_t *) data);
case BALANCE:
@@ -936,15 +936,15 @@ value_t::operator long() const
}
template <>
-value_t::operator datetime_t() const
+value_t::operator ptime() const
{
switch (type) {
case BOOLEAN:
throw new value_error("Cannot convert a boolean to a date/time");
case INTEGER:
- return *((long *) data);
+ throw new value_error("Cannot convert an integer to a date/time");
case DATETIME:
- return *((datetime_t *) data);
+ return *((ptime *) data);
case AMOUNT:
throw new value_error("Cannot convert an amount to a date/time");
case BALANCE:
@@ -965,7 +965,7 @@ value_t::operator datetime_t() const
break;
}
assert(0);
- return 0;
+ return ptime();
}
template <>
@@ -1039,15 +1039,15 @@ bool value_t::operator OP(const value_t& val) \
{ \
switch (type) { \
case BOOLEAN: \
- switch (val.type) { \
+ switch (val.type) { \
case BOOLEAN: \
- return *((bool *) data) OP *((bool *) val.data); \
+ return *((bool *) data) OP *((bool *) val.data); \
\
case INTEGER: \
return *((bool *) data) OP bool(*((long *) val.data)); \
\
case DATETIME: \
- return *((bool *) data) OP bool(*((datetime_t *) val.data)); \
+ throw new value_error("Cannot compare a boolean to a date/time"); \
\
case AMOUNT: \
return *((bool *) data) OP bool(*((amount_t *) val.data)); \
@@ -1056,16 +1056,16 @@ bool value_t::operator OP(const value_t& val) \
return *((bool *) data) OP bool(*((balance_t *) val.data)); \
\
case BALANCE_PAIR: \
- return *((bool *) data) OP bool(*((balance_pair_t *) val.data)); \
+ return *((bool *) data) OP bool(*((balance_pair_t *) val.data)); \
\
case STRING: \
throw new value_error("Cannot compare a boolean to a string"); \
case XML_NODE: \
throw new value_error("Cannot compare a boolean to an XML node"); \
case POINTER: \
- throw new value_error("Cannot compare a boolean to a pointer"); \
+ throw new value_error("Cannot compare a boolean to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare a boolean to a sequence"); \
+ throw new value_error("Cannot compare a boolean to a sequence"); \
\
default: \
assert(0); \
@@ -1074,7 +1074,7 @@ bool value_t::operator OP(const value_t& val) \
break; \
\
case INTEGER: \
- switch (val.type) { \
+ switch (val.type) { \
case BOOLEAN: \
return (*((long *) data) OP \
((long) *((bool *) val.data))); \
@@ -1083,8 +1083,7 @@ bool value_t::operator OP(const value_t& val) \
return (*((long *) data) OP *((long *) val.data)); \
\
case DATETIME: \
- return (*((long *) data) OP \
- ((long) *((datetime_t *) val.data))); \
+ throw new value_error("Cannot compare an integer to a date/time"); \
\
case AMOUNT: \
return (amount_t(*((long *) data)) OP \
@@ -1096,14 +1095,14 @@ bool value_t::operator OP(const value_t& val) \
\
case BALANCE_PAIR: \
return (balance_pair_t(*((long *) data)) OP \
- *((balance_pair_t *) val.data)); \
+ *((balance_pair_t *) val.data)); \
\
case STRING: \
throw new value_error("Cannot compare an integer to a string"); \
case XML_NODE: \
throw new value_error("Cannot compare an integer to an XML node"); \
case POINTER: \
- throw new value_error("Cannot compare an integer to a pointer"); \
+ throw new value_error("Cannot compare an integer to a pointer"); \
case SEQUENCE: \
throw new value_error("Cannot compare an integer to a sequence"); \
\
@@ -1114,17 +1113,15 @@ bool value_t::operator OP(const value_t& val) \
break; \
\
case DATETIME: \
- switch (val.type) { \
+ switch (val.type) { \
case BOOLEAN: \
throw new value_error("Cannot compare a date/time to a boolean"); \
\
case INTEGER: \
- return (*((datetime_t *) data) OP \
- datetime_t(*((long *) val.data))); \
+ throw new value_error("Cannot compare a date/time to an integer"); \
\
case DATETIME: \
- return (*((datetime_t *) data) OP \
- *((datetime_t *) val.data)); \
+ return *((ptime *) data) OP *((ptime *) val.data); \
\
case AMOUNT: \
throw new value_error("Cannot compare a date/time to an amount"); \
@@ -1148,19 +1145,19 @@ bool value_t::operator OP(const value_t& val) \
break; \
\
case AMOUNT: \
- switch (val.type) { \
+ switch (val.type) { \
case BOOLEAN: \
throw new value_error("Cannot compare an amount to a boolean"); \
\
case INTEGER: \
return (*((amount_t *) data) OP \
- amount_t(*((long *) val.data))); \
+ amount_t(*((long *) val.data))); \
\
case DATETIME: \
throw new value_error("Cannot compare an amount to a date/time"); \
\
case AMOUNT: \
- return *((amount_t *) data) OP *((amount_t *) val.data); \
+ return *((amount_t *) data) OP *((amount_t *) val.data); \
\
case BALANCE: \
return (balance_t(*((amount_t *) data)) OP \
@@ -1168,16 +1165,16 @@ bool value_t::operator OP(const value_t& val) \
\
case BALANCE_PAIR: \
return (balance_t(*((amount_t *) data)) OP \
- *((balance_pair_t *) val.data)); \
+ *((balance_pair_t *) val.data)); \
\
case STRING: \
throw new value_error("Cannot compare an amount to a string"); \
case XML_NODE: \
throw new value_error("Cannot compare an amount to an XML node"); \
case POINTER: \
- throw new value_error("Cannot compare an amount to a pointer"); \
+ throw new value_error("Cannot compare an amount to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare an amount to a sequence"); \
+ throw new value_error("Cannot compare an amount to a sequence"); \
\
default: \
assert(0); \
@@ -1186,7 +1183,7 @@ bool value_t::operator OP(const value_t& val) \
break; \
\
case BALANCE: \
- switch (val.type) { \
+ switch (val.type) { \
case BOOLEAN: \
throw new value_error("Cannot compare a balance to a boolean"); \
\
@@ -1197,23 +1194,23 @@ bool value_t::operator OP(const value_t& val) \
throw new value_error("Cannot compare a balance to a date/time"); \
\
case AMOUNT: \
- return *((balance_t *) data) OP *((amount_t *) val.data); \
+ return *((balance_t *) data) OP *((amount_t *) val.data); \
\
case BALANCE: \
return *((balance_t *) data) OP *((balance_t *) val.data); \
\
case BALANCE_PAIR: \
return (*((balance_t *) data) OP \
- ((balance_pair_t *) val.data)->quantity); \
+ ((balance_pair_t *) val.data)->quantity); \
\
case STRING: \
throw new value_error("Cannot compare a balance to a string"); \
case XML_NODE: \
throw new value_error("Cannot compare a balance to an XML node"); \
case POINTER: \
- throw new value_error("Cannot compare a balance to a pointer"); \
+ throw new value_error("Cannot compare a balance to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare a balance to a sequence"); \
+ throw new value_error("Cannot compare a balance to a sequence"); \
\
default: \
assert(0); \
@@ -1222,9 +1219,9 @@ bool value_t::operator OP(const value_t& val) \
break; \
\
case BALANCE_PAIR: \
- switch (val.type) { \
+ switch (val.type) { \
case BOOLEAN: \
- throw new value_error("Cannot compare a balance pair to a boolean"); \
+ throw new value_error("Cannot compare a balance pair to a boolean"); \
\
case INTEGER: \
return (((balance_pair_t *) data)->quantity OP \
@@ -1243,7 +1240,7 @@ bool value_t::operator OP(const value_t& val) \
\
case BALANCE_PAIR: \
return (*((balance_pair_t *) data) OP \
- *((balance_pair_t *) val.data)); \
+ *((balance_pair_t *) val.data)); \
\
case STRING: \
throw new value_error("Cannot compare a balance pair to a string"); \
@@ -1261,7 +1258,7 @@ bool value_t::operator OP(const value_t& val) \
break; \
\
case STRING: \
- switch (val.type) { \
+ switch (val.type) { \
case BOOLEAN: \
throw new value_error("Cannot compare a string to a boolean"); \
case INTEGER: \
@@ -1284,9 +1281,9 @@ bool value_t::operator OP(const value_t& val) \
(*(xml::node_t **) val.data)->text()); \
\
case POINTER: \
- throw new value_error("Cannot compare a string to a pointer"); \
+ throw new value_error("Cannot compare a string to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare a string to a sequence"); \
+ throw new value_error("Cannot compare a string to a sequence"); \
\
default: \
assert(0); \
@@ -1295,13 +1292,13 @@ bool value_t::operator OP(const value_t& val) \
break; \
\
case XML_NODE: \
- switch (val.type) { \
+ switch (val.type) { \
case BOOLEAN: \
throw new value_error("Cannot compare an XML node to a boolean"); \
case INTEGER: \
- throw new value_error("Cannot compare an XML node to an integer"); \
+ throw new value_error("Cannot compare an XML node to an integer"); \
case DATETIME: \
- throw new value_error("Cannot compare an XML node to a date/time"); \
+ throw new value_error("Cannot compare an XML node to a date/time"); \
case AMOUNT: \
throw new value_error("Cannot compare an XML node to an amount"); \
case BALANCE: \
@@ -1329,7 +1326,7 @@ bool value_t::operator OP(const value_t& val) \
break; \
\
case POINTER: \
- switch (val.type) { \
+ switch (val.type) { \
case BOOLEAN: \
throw new value_error("Cannot compare a pointer to a boolean"); \
case INTEGER: \
@@ -1349,7 +1346,7 @@ bool value_t::operator OP(const value_t& val) \
case POINTER: \
return (*((void **) data) OP *((void **) val.data)); \
case SEQUENCE: \
- throw new value_error("Cannot compare a pointer to a sequence"); \
+ throw new value_error("Cannot compare a pointer to a sequence"); \
\
default: \
assert(0); \
@@ -1414,8 +1411,8 @@ void value_t::cast(type_t cast_type)
case INTEGER:
break;
case DATETIME:
- *((datetime_t *) data) = datetime_t(*((long *) data));
- break;
+ throw new value_error("Cannot convert an integer to a date/time");
+
case AMOUNT:
new((amount_t *)data) amount_t(*((long *) data));
break;
@@ -1447,11 +1444,10 @@ void value_t::cast(type_t cast_type)
case DATETIME:
switch (cast_type) {
case BOOLEAN:
- *((bool *) data) = *((datetime_t *) data);
+ *((bool *) data) = ! ((ptime *) data)->is_not_a_date_time();
break;
case INTEGER:
- *((long *) data) = *((datetime_t *) data);
- break;
+ throw new value_error("Cannot convert a date/time to an integer");
case DATETIME:
break;
case AMOUNT:
@@ -1856,7 +1852,7 @@ void value_t::abs()
}
}
-value_t value_t::value(const datetime_t& moment) const
+value_t value_t::value(const ptime& moment) const
{
switch (type) {
case BOOLEAN:
@@ -2014,18 +2010,18 @@ value_t value_t::date() const
case BOOLEAN:
throw new value_error("Cannot find the date of a boolean");
case INTEGER:
- return datetime_t();
+ return ptime();
case DATETIME:
return *this;
case AMOUNT:
- return datetime_t(((amount_t *) data)->date());
+ return ptime(((amount_t *) data)->date());
case BALANCE:
- return datetime_t(((balance_t *) data)->date());
+ return ptime(((balance_t *) data)->date());
case BALANCE_PAIR:
- return datetime_t(((balance_pair_t *) data)->quantity.date());
+ return ptime(((balance_pair_t *) data)->quantity.date());
case STRING:
throw new value_error("Cannot find the date of a string");
@@ -2209,7 +2205,7 @@ std::ostream& operator<<(std::ostream& out, const value_t& val)
out << *(long *) val.data;
break;
case value_t::DATETIME:
- out << *(datetime_t *) val.data;
+ out << *(ptime *) val.data;
break;
case value_t::AMOUNT:
out << *(amount_t *) val.data;
@@ -2284,7 +2280,7 @@ void value_context::describe(std::ostream& out) const throw()
out << *((long *) bal->data);
break;
case value_t::DATETIME:
- out << *((datetime_t *) bal->data);
+ out << *((ptime *) bal->data);
break;
case value_t::AMOUNT:
out << *((amount_t *) bal->data);
@@ -2415,7 +2411,7 @@ void export_value()
.def(init<std::string>())
.def(init<double>())
.def(init<long>())
- .def(init<datetime_t>())
+ .def(init<ptime>())
.def(self + self)
.def(self + other<std::string>())
@@ -2517,7 +2513,7 @@ void export_value()
.def(self < other<balance_t>())
.def(self < other<amount_t>())
.def(self < long())
- .def(self < other<datetime_t>())
+ .def(self < other<ptime>())
.def(self < double())
.def(other<std::string>() < self)
@@ -2525,7 +2521,7 @@ void export_value()
.def(other<balance_t>() < self)
.def(other<amount_t>() < self)
.def(long() < self)
- .def(other<datetime_t>() < self)
+ .def(other<ptime>() < self)
.def(double() < self)
.def(self <= self)
@@ -2534,7 +2530,7 @@ void export_value()
.def(self <= other<balance_t>())
.def(self <= other<amount_t>())
.def(self <= long())
- .def(self <= other<datetime_t>())
+ .def(self <= other<ptime>())
.def(self <= double())
.def(other<std::string>() <= self)
@@ -2542,7 +2538,7 @@ void export_value()
.def(other<balance_t>() <= self)
.def(other<amount_t>() <= self)
.def(long() <= self)
- .def(other<datetime_t>() <= self)
+ .def(other<ptime>() <= self)
.def(double() <= self)
.def(self > self)
@@ -2551,7 +2547,7 @@ void export_value()
.def(self > other<balance_t>())
.def(self > other<amount_t>())
.def(self > long())
- .def(self > other<datetime_t>())
+ .def(self > other<ptime>())
.def(self > double())
.def(other<std::string>() > self)
@@ -2559,7 +2555,7 @@ void export_value()
.def(other<balance_t>() > self)
.def(other<amount_t>() > self)
.def(long() > self)
- .def(other<datetime_t>() > self)
+ .def(other<ptime>() > self)
.def(double() > self)
.def(self >= self)
@@ -2568,7 +2564,7 @@ void export_value()
.def(self >= other<balance_t>())
.def(self >= other<amount_t>())
.def(self >= long())
- .def(self >= other<datetime_t>())
+ .def(self >= other<ptime>())
.def(self >= double())
.def(other<std::string>() >= self)
@@ -2576,7 +2572,7 @@ void export_value()
.def(other<balance_t>() >= self)
.def(other<amount_t>() >= self)
.def(long() >= self)
- .def(other<datetime_t>() >= self)
+ .def(other<ptime>() >= self)
.def(double() >= self)
.def(self == self)
@@ -2585,7 +2581,7 @@ void export_value()
.def(self == other<balance_t>())
.def(self == other<amount_t>())
.def(self == long())
- .def(self == other<datetime_t>())
+ .def(self == other<ptime>())
.def(self == double())
.def(other<std::string>() == self)
@@ -2593,7 +2589,7 @@ void export_value()
.def(other<balance_t>() == self)
.def(other<amount_t>() == self)
.def(long() == self)
- .def(other<datetime_t>() == self)
+ .def(other<ptime>() == self)
.def(double() == self)
.def(self != self)
@@ -2602,7 +2598,7 @@ void export_value()
.def(self != other<balance_t>())
.def(self != other<amount_t>())
.def(self != long())
- .def(self != other<datetime_t>())
+ .def(self != other<ptime>())
.def(self != double())
.def(other<std::string>() != self)
@@ -2610,7 +2606,7 @@ void export_value()
.def(other<balance_t>() != self)
.def(other<amount_t>() != self)
.def(long() != self)
- .def(other<datetime_t>() != self)
+ .def(other<ptime>() != self)
.def(double() != self)
.def(! self)
diff --git a/value.h b/value.h
index 135fa7be..81fb9371 100644
--- a/value.h
+++ b/value.h
@@ -63,9 +63,9 @@ class value_t
*((long *) data) = val;
type = INTEGER;
}
- value_t(const datetime_t val) {
- TRACE_CTOR("value_t(const datetime_t)");
- *((datetime_t *) data) = val;
+ value_t(const ptime val) {
+ TRACE_CTOR("value_t(const ptime)");
+ *((ptime *) data) = val;
type = DATETIME;
}
value_t(const unsigned long val) {
@@ -144,10 +144,10 @@ class value_t
}
return *this;
}
- value_t& operator=(const datetime_t val) {
- if ((datetime_t *) data != &val) {
+ value_t& operator=(const ptime val) {
+ if ((ptime *) data != &val) {
destroy();
- *((datetime_t *) data) = val;
+ *((ptime *) data) = val;
type = DATETIME;
}
return *this;
@@ -276,7 +276,7 @@ class value_t
bool to_boolean() const;
long to_integer() const;
- datetime_t to_datetime() const;
+ ptime to_datetime() const;
amount_t to_amount() const;
balance_t to_balance() const;
balance_pair_t to_balance_pair() const;
@@ -417,7 +417,7 @@ class value_t
case INTEGER:
return *((long *) data) == 0;
case DATETIME:
- return ! *((datetime_t *) data);
+ return ((ptime *) data)->is_not_a_date_time();
case AMOUNT:
return ((amount_t *) data)->realzero();
case BALANCE:
@@ -450,7 +450,7 @@ class value_t
const bool keep_tag = amount_t::keep_tag) const;
value_t& add(const amount_t& amount, const amount_t * cost = NULL);
- value_t value(const datetime_t& moment) const;
+ value_t value(const ptime& moment) const;
void reduce();
value_t reduced() const {
@@ -466,35 +466,57 @@ class value_t
const int latter_width = -1) const;
};
-#define DEF_VALUE_AUX_OP(OP) \
- inline value_t operator OP(const balance_pair_t& val, \
- const value_t& obj) { \
- return value_t(val) OP obj; \
- } \
- inline value_t operator OP(const balance_t& val, \
- const value_t& obj) { \
- return value_t(val) OP obj; \
- } \
- inline value_t operator OP(const amount_t& val, \
- const value_t& obj) { \
- return value_t(val) OP obj; \
- } \
- template <typename T> \
- inline value_t operator OP(T val, const value_t& obj) { \
- return value_t(val) OP obj; \
- }
-
-DEF_VALUE_AUX_OP(+)
-DEF_VALUE_AUX_OP(-)
-DEF_VALUE_AUX_OP(*)
-DEF_VALUE_AUX_OP(/)
-
-DEF_VALUE_AUX_OP(<)
-DEF_VALUE_AUX_OP(<=)
-DEF_VALUE_AUX_OP(>)
-DEF_VALUE_AUX_OP(>=)
-DEF_VALUE_AUX_OP(==)
-DEF_VALUE_AUX_OP(!=)
+#define DEFINE_VALUE_OPERATORS(T, OP) \
+inline value_t operator OP(const T& val, const value_t& obj) { \
+ return value_t(val) OP obj; \
+}
+
+DEFINE_VALUE_OPERATORS(bool, ==)
+DEFINE_VALUE_OPERATORS(bool, !=)
+
+DEFINE_VALUE_OPERATORS(long, +)
+DEFINE_VALUE_OPERATORS(long, -)
+DEFINE_VALUE_OPERATORS(long, *)
+DEFINE_VALUE_OPERATORS(long, /)
+DEFINE_VALUE_OPERATORS(long, <)
+DEFINE_VALUE_OPERATORS(long, <=)
+DEFINE_VALUE_OPERATORS(long, >)
+DEFINE_VALUE_OPERATORS(long, >=)
+DEFINE_VALUE_OPERATORS(long, ==)
+DEFINE_VALUE_OPERATORS(long, !=)
+
+DEFINE_VALUE_OPERATORS(amount_t, +)
+DEFINE_VALUE_OPERATORS(amount_t, -)
+DEFINE_VALUE_OPERATORS(amount_t, *)
+DEFINE_VALUE_OPERATORS(amount_t, /)
+DEFINE_VALUE_OPERATORS(amount_t, <)
+DEFINE_VALUE_OPERATORS(amount_t, <=)
+DEFINE_VALUE_OPERATORS(amount_t, >)
+DEFINE_VALUE_OPERATORS(amount_t, >=)
+DEFINE_VALUE_OPERATORS(amount_t, ==)
+DEFINE_VALUE_OPERATORS(amount_t, !=)
+
+DEFINE_VALUE_OPERATORS(balance_t, +)
+DEFINE_VALUE_OPERATORS(balance_t, -)
+DEFINE_VALUE_OPERATORS(balance_t, *)
+DEFINE_VALUE_OPERATORS(balance_t, /)
+DEFINE_VALUE_OPERATORS(balance_t, <)
+DEFINE_VALUE_OPERATORS(balance_t, <=)
+DEFINE_VALUE_OPERATORS(balance_t, >)
+DEFINE_VALUE_OPERATORS(balance_t, >=)
+DEFINE_VALUE_OPERATORS(balance_t, ==)
+DEFINE_VALUE_OPERATORS(balance_t, !=)
+
+DEFINE_VALUE_OPERATORS(balance_pair_t, +)
+DEFINE_VALUE_OPERATORS(balance_pair_t, -)
+DEFINE_VALUE_OPERATORS(balance_pair_t, *)
+DEFINE_VALUE_OPERATORS(balance_pair_t, /)
+DEFINE_VALUE_OPERATORS(balance_pair_t, <)
+DEFINE_VALUE_OPERATORS(balance_pair_t, <=)
+DEFINE_VALUE_OPERATORS(balance_pair_t, >)
+DEFINE_VALUE_OPERATORS(balance_pair_t, >=)
+DEFINE_VALUE_OPERATORS(balance_pair_t, ==)
+DEFINE_VALUE_OPERATORS(balance_pair_t, !=)
template <typename T>
value_t::operator T() const
@@ -505,7 +527,7 @@ value_t::operator T() const
case INTEGER:
return *(long *) data;
case DATETIME:
- return *(datetime_t *) data;
+ return *(ptime *) data;
case AMOUNT:
return *(amount_t *) data;
case BALANCE:
@@ -529,7 +551,7 @@ value_t::operator T() const
template <> value_t::operator bool() const;
template <> value_t::operator long() const;
-template <> value_t::operator datetime_t() const;
+template <> value_t::operator ptime() const;
template <> value_t::operator double() const;
template <> value_t::operator std::string() const;
diff --git a/xml.cc b/xml.cc
index 7de8444e..33f98666 100644
--- a/xml.cc
+++ b/xml.cc
@@ -1,6 +1,5 @@
#include "xml.h"
#include "journal.h"
-#include "datetime.h"
#include "error.h"
#include <iostream>