summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/annotate.cc2
-rw-r--r--src/filters.cc9
-rw-r--r--src/generate.cc4
-rw-r--r--src/global.cc6
-rw-r--r--src/quotes.cc2
-rw-r--r--src/report.cc10
-rw-r--r--src/report.h14
-rw-r--r--src/session.cc2
-rw-r--r--src/session.h6
-rw-r--r--src/times.cc345
-rw-r--r--src/times.h41
-rw-r--r--src/value.cc17
-rw-r--r--src/value.h2
-rw-r--r--test/baseline/opt-csv-format.test4
-rw-r--r--test/baseline/opt-prices-format.test10
-rw-r--r--test/baseline/opt-pricesdb-format.test10
-rw-r--r--test/regress/BBFA1759.test4
17 files changed, 358 insertions, 130 deletions
diff --git a/src/annotate.cc b/src/annotate.cc
index 1ea39b5d..c6084f7f 100644
--- a/src/annotate.cc
+++ b/src/annotate.cc
@@ -127,7 +127,7 @@ void annotation_t::print(std::ostream& out, bool keep_base) const
<< '}';
if (date)
- out << " [" << format_date(*date, string("%Y/%m/%d")) << ']';
+ out << " [" << format_date(*date, FMT_WRITTEN) << ']';
if (tag)
out << " (" << *tag << ')';
diff --git a/src/filters.cc b/src/filters.cc
index 967e0843..5b087eea 100644
--- a/src/filters.cc
+++ b/src/filters.cc
@@ -531,15 +531,14 @@ void subtotal_posts::report_subtotal(const char * spec_fmt,
std::ostringstream out_date;
if (spec_fmt) {
- out_date << format_date(*range_finish, string(spec_fmt));
+ out_date << format_date(*range_finish, FMT_CUSTOM, spec_fmt);
}
else if (date_format) {
- string fmt = "- ";
- fmt += *date_format;
- out_date << format_date(*range_finish, string(fmt));
+ out_date << "- " << format_date(*range_finish, FMT_CUSTOM,
+ date_format->c_str());
}
else {
- out_date << format_date(*range_finish, std::string("- ") + output_date_format);
+ out_date << "- " << format_date(*range_finish);
}
xact_temps.push_back(xact_t());
diff --git a/src/generate.cc b/src/generate.cc
index 8796f0bf..ebbc3cd7 100644
--- a/src/generate.cc
+++ b/src/generate.cc
@@ -321,11 +321,11 @@ void generate_posts_iterator::generate_note(std::ostream& out)
void generate_posts_iterator::generate_xact(std::ostream& out)
{
- out << format_date(next_date, string("%Y/%m/%d"));
+ out << format_date(next_date, FMT_WRITTEN);
next_date += gregorian::days(six_gen());
if (truth_gen()) {
out << '=';
- out << format_date(next_eff_date, string("%Y/%m/%d"));
+ out << format_date(next_eff_date, FMT_WRITTEN);
next_eff_date += gregorian::days(six_gen());
}
out << ' ';
diff --git a/src/global.cc b/src/global.cc
index 24716fae..02c9e79a 100644
--- a/src/global.cc
+++ b/src/global.cc
@@ -433,8 +433,10 @@ void global_scope_t::normalize_report_options(const string& verb)
rep.session.commodity_pool->price_db = none;
if (rep.HANDLED(date_format_)) {
- output_datetime_format = rep.HANDLER(date_format_).str() + " %H:%M:%S";
- output_date_format = rep.HANDLER(date_format_).str();
+ set_date_format(rep.HANDLER(date_format_).str().c_str());
+ }
+ if (rep.HANDLED(datetime_format_)) {
+ set_datetime_format(rep.HANDLER(datetime_format_).str().c_str());
}
if (rep.HANDLED(start_of_week_)) {
if (optional<date_time::weekdays> weekday =
diff --git a/src/quotes.cc b/src/quotes.cc
index d4be462e..797e6dd5 100644
--- a/src/quotes.cc
+++ b/src/quotes.cc
@@ -86,7 +86,7 @@ commodity_quote_from_script(commodity_t& commodity,
std::ios_base::out | std::ios_base::app);
#endif
database << "P "
- << format_datetime(point->when, string("%Y/%m/%d %H:%M:%S"))
+ << format_datetime(point->when, FMT_WRITTEN)
<< " " << commodity.symbol()
<< " " << point->price
<< std::endl;
diff --git a/src/report.cc b/src/report.cc
index 661fdfbe..9c8ad8ba 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -263,9 +263,12 @@ value_t report_t::fn_join(call_scope_t& scope)
value_t report_t::fn_format_date(call_scope_t& scope)
{
- interactive_t args(scope, "ds");
- return string_value(format_date(args.get<date_t>(0),
- args.get<string>(1)));
+ interactive_t args(scope, "d&s");
+ if (args.has(1))
+ return string_value(format_date(args.get<date_t>(0), FMT_CUSTOM,
+ args.get<string>(1).c_str()));
+ else
+ return string_value(format_date(args.get<date_t>(0), FMT_PRINTED));
}
value_t report_t::fn_ansify_if(call_scope_t& scope)
@@ -521,6 +524,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
case 'd':
OPT(daily);
else OPT(date_format_);
+ else OPT(datetime_format_);
else OPT(depth_);
else OPT(deviation);
else OPT_(display_);
diff --git a/src/report.h b/src/report.h
index 71dc4ca2..5921a154 100644
--- a/src/report.h
+++ b/src/report.h
@@ -218,6 +218,7 @@ public:
HANDLER(current).report(out);
HANDLER(daily).report(out);
HANDLER(date_format_).report(out);
+ HANDLER(datetime_format_).report(out);
HANDLER(depth_).report(out);
HANDLER(deviation).report(out);
HANDLER(display_).report(out);
@@ -412,10 +413,8 @@ public:
parent->HANDLER(period_).on(string("--daily"), "daily");
});
- OPTION__(report_t, date_format_, // -y
- CTOR(report_t, date_format_) {
- on(none, "%y-%b-%d");
- });
+ OPTION(report_t, date_format_);
+ OPTION(report_t, datetime_format_);
OPTION_(report_t, depth_, DO_(scope) {
interactive_t args(scope, "sl");
@@ -633,9 +632,9 @@ public:
OPTION__(report_t, print_format_, CTOR(report_t, print_format_) {
on(none,
- "%(format_date(xact.date, \"%Y/%m/%d\"))"
+ "%(xact.date)"
"%(!effective & xact.effective_date ?"
- " \"=\" + format_date(xact.effective_date, \"%Y/%m/%d\") : \"\")"
+ " \"=\" + xact.effective_date : \"\")"
"%(xact.cleared ? \" *\" : (xact.pending ? \" !\" : \"\"))"
"%(code ? \" (\" + code + \")\" :"
" \"\") %(payee)%(xact.comment)\n"
@@ -673,7 +672,8 @@ public:
OPTION__(report_t, register_format_, CTOR(report_t, register_format_) {
on(none,
- "%(ansify_if(justify(date, date_width), green if color & date > today))"
+ "%(ansify_if(justify(format_date(date), date_width), green "
+ " if color & date > today))"
" %(ansify_if(justify(truncated(payee, payee_width), payee_width), "
" bold if color & !cleared))"
" %(ansify_if(justify(truncated(account, account_width, abbrev_len), "
diff --git a/src/session.cc b/src/session.cc
index f7a8655b..b46d545e 100644
--- a/src/session.cc
+++ b/src/session.cc
@@ -45,6 +45,7 @@ namespace ledger {
void set_session_context(session_t * session)
{
if (session) {
+ times_initialize();
amount_t::initialize(session->commodity_pool);
// jww (2009-02-04): Is amount_t the right place for parse_conversion to
@@ -57,6 +58,7 @@ void set_session_context(session_t * session)
else if (! session) {
value_t::shutdown();
amount_t::shutdown();
+ times_shutdown();
}
}
diff --git a/src/session.h b/src/session.h
index 894c59fa..a51cdba6 100644
--- a/src/session.h
+++ b/src/session.h
@@ -144,9 +144,9 @@ public:
});
OPTION_(session_t, input_date_format_, DO_(args) {
- // This changes the global variable inside times.h, which affects the
- // basic date parser
- input_date_format = args[1].as_string();
+ // This changes static variables inside times.h, which affects the basic
+ // date parser.
+ set_input_date_format(args[1].as_string().c_str());
});
OPTION(session_t, price_db_);
diff --git a/src/times.cc b/src/times.cc
index 45f7ed10..a00692b4 100644
--- a/src/times.cc
+++ b/src/times.cc
@@ -35,55 +35,177 @@
namespace ledger {
-date_time::weekdays start_of_week = gregorian::Sunday;
-optional<std::string> input_date_format;
-std::string output_datetime_format = "%Y-%m-%d %H:%M:%S";
-std::string output_date_format = "%Y-%m-%d";
+date_time::weekdays start_of_week = gregorian::Sunday;
+
+//#define USE_BOOST_FACETS 1
namespace {
- struct date_format_t {
- const char * format;
- bool has_year;
- date_format_t(const char * _format, bool _has_year)
- : format(_format), has_year(_has_year) {}
- };
+ template <typename T, typename InputFacetType, typename OutputFacetType>
+ class temporal_io_t : public noncopyable
+ {
+ const char * fmt_str;
+#if defined(USE_BOOST_FACETS)
+ std::istringstream input_stream;
+ std::ostringstream output_stream;
+ InputFacetType * input_facet;
+ OutputFacetType * output_facet;
+ std::string temp_string;
+#endif
- const date_format_t formats[] = {
- date_format_t("%m/%d", false),
- date_format_t("%Y/%m/%d", true),
- date_format_t("%Y/%m", true),
- date_format_t("%y/%m/%d", true),
- date_format_t("%m.%d", false),
- date_format_t("%Y.%m.%d", true),
- date_format_t("%Y.%m", true),
- date_format_t("%y.%m.%d", true),
- date_format_t("%m-%d", false),
- date_format_t("%Y-%m-%d", true),
- date_format_t("%Y-%m", true),
- date_format_t("%y-%m-%d", true)
+ public:
+ bool has_year;
+ bool input;
+
+ temporal_io_t(const char * _fmt_str, bool _input)
+ : fmt_str(_fmt_str), has_year(icontains(fmt_str, "%y")),
+ input(_input) {
+#if defined(USE_BOOST_FACETS)
+ if (input) {
+ input_facet = new InputFacetType(fmt_str);
+ input_stream.imbue(std::locale(std::locale::classic(), input_facet));
+ } else {
+ output_facet = new OutputFacetType(fmt_str);
+ output_stream.imbue(std::locale(std::locale::classic(), output_facet));
+ }
+#endif
+ }
+
+ void set_format(const char * fmt) {
+ fmt_str = fmt;
+ has_year = icontains(fmt_str, "%y");
+
+#if defined(USE_BOOST_FACETS)
+ if (input)
+ input_facet->format(fmt_str);
+ else
+ output_facet->format(fmt_str);
+#endif
+ }
+
+ T parse(const char * str) {
+ }
+
+ std::string format(const T& when) {
+#if defined(USE_BOOST_FACETS)
+ output_stream.str(temp_string);
+ output_stream.seekp(std::ios_base::beg);
+ output_stream.clear();
+ output_stream << when;
+ return output_stream.str();
+#else
+ std::tm data(to_tm(when));
+ char buf[128];
+ std::strftime(buf, 127, fmt_str, &data);
+ return buf;
+#endif
+ }
};
- date_t parse_date_mask_routine(const char * date_str, const date_format_t& df,
- optional<date_t::year_type> year, bool& saw_year)
+ template <>
+ datetime_t temporal_io_t<datetime_t, posix_time::time_input_facet,
+ posix_time::time_facet>
+ ::parse(const char * str)
{
- std::string str(date_str);
+#if defined(USE_BOOST_FACETS)
+ input_stream.seekg(std::ios_base::beg);
+ input_stream.clear();
+ input_stream.str(str);
- gregorian::date_input_facet * facet(new gregorian::date_input_facet(df.format));
- std::istringstream sstr(str);
- sstr.imbue(std::locale(sstr.getloc(), facet));
+ datetime_t when;
+ input_stream >> when;
+#if defined(DEBUG_ON)
+ if (when.is_not_a_date_time())
+ DEBUG("times.parse", "Failed to parse '" << str
+ << "' using pattern '" << fmt_str << "'");
+#endif
- date_t when;
- sstr >> when;
+ if (! when.is_not_a_date_time() &&
+ input_stream.good() && ! input_stream.eof() &&
+ input_stream.peek() != EOF)
+ return datetime_t();
+ return when;
+#else
+ std::tm data;
+ std::memset(&data, 0, sizeof(std::tm));
+ if (strptime(str, fmt_str, &data))
+ return posix_time::ptime_from_tm(data);
+ else
+ return datetime_t();
+#endif
+ }
- if (! when.is_not_a_date()) {
- if (sstr.good() && ! sstr.eof() && sstr.peek() != EOF)
+ template <>
+ date_t temporal_io_t<date_t, gregorian::date_input_facet,
+ gregorian::date_facet>
+ ::parse(const char * str)
+ {
+#if defined(USE_BOOST_FACETS)
+ input_stream.seekg(std::ios_base::beg);
+ input_stream.clear();
+ input_stream.str(str);
+
+ date_t when;
+ input_stream >> when;
+#if defined(DEBUG_ON)
+ if (when.is_not_a_date())
+ DEBUG("times.parse", "Failed to parse '" << str
+ << "' using pattern '" << fmt_str << "'");
+#endif
+
+ if (! when.is_not_a_date() &&
+ input_stream.good() && ! input_stream.eof() &&
+ input_stream.peek() != EOF)
return date_t();
+ return when;
+#else
+ std::tm data;
+ std::memset(&data, 0, sizeof(std::tm));
+ data.tm_mday = 1; // some formats have no day
+ if (strptime(str, fmt_str, &data))
+ return gregorian::date_from_tm(data);
+ else
+ return date_t();
+#endif
+ }
+
+ typedef temporal_io_t<datetime_t, posix_time::time_input_facet,
+ posix_time::time_facet> datetime_io_t;
+ typedef temporal_io_t<date_t, gregorian::date_input_facet,
+ gregorian::date_facet> date_io_t;
+
+ std::auto_ptr<datetime_io_t> written_datetime_io;
+ std::auto_ptr<datetime_io_t> printed_datetime_io;
+ std::auto_ptr<date_io_t> input_date_io;
+ std::auto_ptr<date_io_t> written_date_io;
+ std::auto_ptr<date_io_t> printed_date_io;
+
+ std::vector<shared_ptr<date_io_t> > readers;
+
+ date_t parse_date_mask_routine(const char * date_str, date_io_t& io,
+ optional<date_t::year_type> year,
+ bool& saw_year)
+ {
+ date_t when;
+
+ if (std::strchr(date_str, '/')) {
+ when = io.parse(date_str);
+ } else {
+ char buf[128];
+ VERIFY(std::strlen(date_str) < 127);
+ std::strcpy(buf, date_str);
+
+ for (char * p = buf; *p; p++)
+ if (*p == '.' || *p == '-')
+ *p = '/';
+
+ when = io.parse(buf);
+ }
+ if (! when.is_not_a_date()) {
DEBUG("times.parse", "Parsed date string: " << date_str);
- DEBUG("times.parse", "Parsed result is: " << when);
- DEBUG("times.parse", "Format used was: " << df.format);
+ DEBUG("times.parse", "Parsed result is: " << when);
- if (! df.has_year) {
+ if (! io.has_year) {
saw_year = false;
when = date_t(year ? *year : CURRENT_DATE().year(),
@@ -98,25 +220,24 @@ namespace {
return when;
}
- date_t parse_date_mask(const char * date_str, optional<date_t::year_type> year,
- bool& saw_year)
+ date_t parse_date_mask(const char * date_str,
+ optional<date_t::year_type> year, bool& saw_year)
{
- if (input_date_format) {
- date_format_t df(input_date_format->c_str(), true);
- if (! icontains(*input_date_format, "%y"))
- df.has_year = false;
- date_t when = parse_date_mask_routine(date_str, df, year, saw_year);
+ if (input_date_io.get()) {
+ date_t when = parse_date_mask_routine(date_str, *input_date_io.get(),
+ year, saw_year);
if (! when.is_not_a_date())
return when;
}
- for (uint8_t i = 0; i < (sizeof(formats) / sizeof(date_format_t)); i++) {
- date_t when = parse_date_mask_routine(date_str, formats[i], year,
- saw_year);
+ foreach (shared_ptr<date_io_t>& reader, readers) {
+ date_t when = parse_date_mask_routine(date_str, *reader.get(),
+ year, saw_year);
if (! when.is_not_a_date())
return when;
}
+ throw_(date_error, _("Invalid date: %1") << date_str);
return date_t();
}
}
@@ -174,16 +295,7 @@ string_to_month_of_year(const std::string& str)
datetime_t parse_datetime(const char * str, optional<date_t::year_type>)
{
- posix_time::time_input_facet * facet
- (new posix_time::time_input_facet("%Y/%m/%d %H:%M:%S"));
-
- std::string temp(str);
- std::istringstream sstr(temp);
- sstr.imbue(std::locale(sstr.getloc(), facet));
-
- datetime_t when;
- sstr >> when;
- return when;
+ return written_datetime_io->parse(str);
}
date_t parse_date(const char * str, optional<date_t::year_type> current_year)
@@ -481,7 +593,7 @@ namespace {
inline void read_lower_word(std::istream& in, string& word) {
in >> word;
- for (int i = 0, l = word.length(); i < l; i++)
+ for (string::size_type i = 0, l = word.length(); i < l; i++)
word[i] = static_cast<char>(std::tolower(word[i]));
}
@@ -662,4 +774,123 @@ void date_interval_t::parse(std::istream& in)
}
}
+namespace {
+ typedef std::map<std::string, datetime_io_t *> datetime_io_map;
+ typedef std::map<std::string, date_io_t *> date_io_map;
+
+ datetime_io_map temp_datetime_io;
+ date_io_map temp_date_io;
+}
+
+std::string format_datetime(const datetime_t& when,
+ const format_type_t format_type,
+ const optional<const char *>& format)
+{
+ if (format_type == FMT_WRITTEN) {
+ return written_datetime_io->format(when);
+ }
+ else if (format_type == FMT_CUSTOM || format) {
+ datetime_io_map::iterator i = temp_datetime_io.find(*format);
+ if (i != temp_datetime_io.end()) {
+ return (*i).second->format(when);
+ } else {
+ datetime_io_t * formatter = new datetime_io_t(*format, false);
+ temp_datetime_io.insert(datetime_io_map::value_type(*format, formatter));
+ return formatter->format(when);
+ }
+ }
+ else if (format_type == FMT_PRINTED) {
+ return printed_datetime_io->format(when);
+ }
+ else {
+ assert(0);
+ return "";
+ }
+}
+
+std::string format_date(const date_t& when,
+ const format_type_t format_type,
+ const optional<const char *>& format)
+{
+ if (format_type == FMT_WRITTEN) {
+ return written_date_io->format(when);
+ }
+ else if (format_type == FMT_CUSTOM || format) {
+ date_io_map::iterator i = temp_date_io.find(*format);
+ if (i != temp_date_io.end()) {
+ return (*i).second->format(when);
+ } else {
+ date_io_t * formatter = new date_io_t(*format, false);
+ temp_date_io.insert(date_io_map::value_type(*format, formatter));
+ return formatter->format(when);
+ }
+ }
+ else if (format_type == FMT_PRINTED) {
+ return printed_date_io->format(when);
+ }
+ else {
+ assert(0);
+ return "";
+ }
+}
+
+namespace {
+ bool is_initialized = false;
+}
+
+void set_datetime_format(const char * format)
+{
+ printed_datetime_io->set_format(format);
+}
+
+void set_date_format(const char * format)
+{
+ printed_date_io->set_format(format);
+}
+
+void set_input_date_format(const char * format)
+{
+ input_date_io.reset(new date_io_t(format, true));
+}
+
+void times_initialize()
+{
+ if (! is_initialized) {
+ written_datetime_io.reset(new datetime_io_t("%Y/%m/%d %H:%M:%S", false));
+ written_date_io.reset(new date_io_t("%Y/%m/%d", false));
+
+ printed_datetime_io.reset(new datetime_io_t("%y-%b-%d %H:%M:%S", false));
+ printed_date_io.reset(new date_io_t("%y-%b-%d", false));
+
+ readers.push_back(shared_ptr<date_io_t>(new date_io_t("%m/%d", true)));
+ readers.push_back(shared_ptr<date_io_t>(new date_io_t("%Y/%m/%d", true)));
+ readers.push_back(shared_ptr<date_io_t>(new date_io_t("%Y/%m", true)));
+ readers.push_back(shared_ptr<date_io_t>(new date_io_t("%y/%m/%d", true)));
+
+ is_initialized = true;
+ }
+}
+
+void times_shutdown()
+{
+ if (is_initialized) {
+ printed_datetime_io.reset();
+ written_datetime_io.reset();
+ input_date_io.reset();
+ printed_date_io.reset();
+ written_date_io.reset();
+
+ readers.clear();
+
+ foreach (datetime_io_map::value_type& pair, temp_datetime_io)
+ checked_delete(pair.second);
+ temp_datetime_io.clear();
+
+ foreach (date_io_map::value_type& pair, temp_date_io)
+ checked_delete(pair.second);
+ temp_date_io.clear();
+
+ is_initialized = false;
+ }
+}
} // namespace ledger
diff --git a/src/times.h b/src/times.h
index 247c9393..c77cde1d 100644
--- a/src/times.h
+++ b/src/times.h
@@ -74,7 +74,6 @@ inline bool is_valid(const date_t& moment) {
#define CURRENT_DATE() boost::gregorian::day_clock::universal_day()
extern date_time::weekdays start_of_week;
-extern optional<std::string> input_date_format;
optional<date_time::weekdays>
string_to_day_of_week(const std::string& str);
@@ -97,33 +96,20 @@ inline date_t parse_date(const std::string& str,
return parse_date(str.c_str(), current_year);
}
-extern std::string output_datetime_format;
+enum format_type_t {
+ FMT_WRITTEN, FMT_PRINTED, FMT_CUSTOM
+};
-inline std::string format_datetime(const datetime_t& when,
- const optional<std::string>& format = none)
-{
- posix_time::time_facet * facet
- (new posix_time::time_facet(format ? format->c_str() :
- output_datetime_format.c_str()));
- std::ostringstream buf;
- buf.imbue(std::locale(std::locale::classic(), facet));
- buf << when;
- return buf.str();
-}
+std::string format_datetime(const datetime_t& when,
+ const format_type_t format_type = FMT_PRINTED,
+ const optional<const char *>& format = none);
+void set_datetime_format(const char * format);
-extern std::string output_date_format;
-
-inline std::string format_date(const date_t& when,
- const optional<std::string>& format = none)
-{
- gregorian::date_facet * facet
- (new gregorian::date_facet(format ? format->c_str() :
- output_date_format.c_str()));
- std::ostringstream buf;
- buf.imbue(std::locale(std::locale::classic(), facet));
- buf << when;
- return buf.str();
-}
+std::string format_date(const date_t& when,
+ const format_type_t format_type = FMT_PRINTED,
+ const optional<const char *>& format = none);
+void set_date_format(const char * format);
+void set_input_date_format(const char * format);
class date_interval_t : public equality_comparable<date_interval_t>
{
@@ -207,6 +193,9 @@ public:
date_interval_t& operator++();
};
+void times_initialize();
+void times_shutdown();
+
std::ostream& operator<<(std::ostream& out,
const date_interval_t::duration_t& duration);
diff --git a/src/value.cc b/src/value.cc
index 0f831cdf..6ce46f5c 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -984,7 +984,7 @@ void value_t::in_place_cast(type_t cast_type)
set_datetime(datetime_t(as_date(), time_duration(0, 0, 0, 0)));
return;
case STRING:
- set_string(format_date(as_date(), string("%Y-%m-%d")));
+ set_string(format_date(as_date(), FMT_WRITTEN));
return;
default:
break;
@@ -996,7 +996,7 @@ void value_t::in_place_cast(type_t cast_type)
set_date(as_datetime().date());
return;
case STRING:
- set_string(format_datetime(as_datetime(), string("%Y-%m-%d %H:%M:%S")));
+ set_string(format_datetime(as_datetime(), FMT_WRITTEN));
return;
default:
break;
@@ -1495,16 +1495,17 @@ void value_t::print(std::ostream& out,
case DATETIME:
if (date_format)
- out << format_datetime(as_datetime(), *date_format);
+ out << format_datetime(as_datetime(), FMT_CUSTOM,
+ date_format->c_str());
else
- out << format_datetime(as_datetime());
+ out << format_datetime(as_datetime(), FMT_WRITTEN);
break;
case DATE:
if (date_format)
- out << format_date(as_date(), *date_format);
+ out << format_date(as_date(), FMT_CUSTOM, date_format->c_str());
else
- out << format_date(as_date());
+ out << format_date(as_date(), FMT_WRITTEN);
break;
case INTEGER:
@@ -1579,10 +1580,10 @@ void value_t::dump(std::ostream& out, const bool relaxed) const
break;
case DATETIME:
- out << '[' << format_datetime(as_datetime()) << ']';
+ out << '[' << format_datetime(as_datetime(), FMT_WRITTEN) << ']';
break;
case DATE:
- out << '[' << format_date(as_date()) << ']';
+ out << '[' << format_date(as_date(), FMT_WRITTEN) << ']';
break;
case INTEGER:
diff --git a/src/value.h b/src/value.h
index f6194c86..b40b9d28 100644
--- a/src/value.h
+++ b/src/value.h
@@ -934,7 +934,7 @@ public:
#define NULL_VALUE (value_t())
-inline value_t string_value(const string& str) {
+inline value_t string_value(const string& str = "") {
return value_t(str, true);
}
diff --git a/test/baseline/opt-csv-format.test b/test/baseline/opt-csv-format.test
index 7efefc0d..d4975f93 100644
--- a/test/baseline/opt-csv-format.test
+++ b/test/baseline/opt-csv-format.test
@@ -4,7 +4,7 @@ csv --csv-format='"%(date)"\n'
Assets:Investments:Vanguard:VMMXX 0.350 VMMXX @ $1.00
Income:Dividends:Vanguard:VMMXX $-0.35
>>>1
-"07-Feb-02"
-"07-Feb-02"
+"2007/02/02"
+"2007/02/02"
>>>2
=== 0
diff --git a/test/baseline/opt-prices-format.test b/test/baseline/opt-prices-format.test
index ec93d9cd..f8033c59 100644
--- a/test/baseline/opt-prices-format.test
+++ b/test/baseline/opt-prices-format.test
@@ -10,10 +10,10 @@ P 2009/02/01 17:30:00 AAPL $50.00
Assets:Brokerage 100 AAPL
Income
>>>1
-09-Jan-01 13:30:00 $10.00
-09-Jan-01 14:30:00 $20.00
-09-Jan-01 15:30:00 $30.00
-09-Jan-01 16:30:00 $40.00
-09-Feb-01 17:30:00 $50.00
+2009/01/01 13:30:00 $10.00
+2009/01/01 14:30:00 $20.00
+2009/01/01 15:30:00 $30.00
+2009/01/01 16:30:00 $40.00
+2009/02/01 17:30:00 $50.00
>>>2
=== 0
diff --git a/test/baseline/opt-pricesdb-format.test b/test/baseline/opt-pricesdb-format.test
index 28998903..b90371cd 100644
--- a/test/baseline/opt-pricesdb-format.test
+++ b/test/baseline/opt-pricesdb-format.test
@@ -10,10 +10,10 @@ P 2009/02/01 17:30:00 AAPL $50.00
Assets:Brokerage 100 AAPL
Income
>>>1
-P 09-Jan-01 $10.00
-P 09-Jan-01 $20.00
-P 09-Jan-01 $30.00
-P 09-Jan-01 $40.00
-P 09-Feb-01 $50.00
+P 2009/01/01 $10.00
+P 2009/01/01 $20.00
+P 2009/01/01 $30.00
+P 2009/01/01 $40.00
+P 2009/02/01 $50.00
>>>2
=== 0
diff --git a/test/regress/BBFA1759.test b/test/regress/BBFA1759.test
index ca6842dc..26862703 100644
--- a/test/regress/BBFA1759.test
+++ b/test/regress/BBFA1759.test
@@ -3,8 +3,8 @@ period june 2008
>>>1
global details =>
- start: 2008-06-01
- end: 2008-07-01
+ start: 08-Jun-01
+ end: 08-Jul-01
factor: 1
>>>2
=== 0