Boost logo

Boost :

From: Martin Adrian (adrianm_at_[hidden])
Date: 2006-11-24 06:09:47

I have a common function to output dates to sql strings. It works like this:

std::locale sqllocale(database_type db_type) {
  switch (db_type) {
    case MSAccess:
      return std::locale(std::locale::classic(),
                         new dt::date_facet("#%m/%d/%Y#"));
    case MSSQLServer:
      return std::locale(std::locale::classic(),
                         new dt::date_facet("{ d '%Y-%m-%d' }"));

std::ostringstream ss; ss.imbue(sqllocale(MSAccess));

ss << "SELECT * FROM tbl WHERE somedate=" << dt::date(2006,11,24);

Now I need to put dates into an excel spreadsheet which uses a date formatted
as a date duration. This can't be expressed via the formatters so I created my
own facet but discovered some strange things:

1. The "put" function of the date_facet calls "do_put_tm" instead of
just "do_put" like standard facets.
2. The virtual "do_put_tm" function takes a struct tm instead of a date
argument. Unfortunatly this means extra work.

My code now looks like this:

case MSExcel: {
  struct excel_date_facet : public dt::date_facet {
    excel_date_facet(::size_t ref_count = 0)
      : dt::date_facet(ref_count) {
    virtual std::ostreambuf_iterator<char> do_put_tm(
      std::ostreambuf_iterator<char> next,
      std::ios_base& a_ios,
      char_type fill_char,
      const tm& tm_value,
      string_type a_format) const
      // Here I now got the date as a struct tm which is pretty useless
      // when I want to calculate a date duration.
      // convert it back to a date
      dt::date d = dt::date_from_tm(tm_value);
      // +2 here because Excel starts on 1900-0-0 and treats 1900
      // as a leap year (!)
      unsigned long days = ((d - dt::date(1900,1,1)).days() + 2);
      return std::use_facet<std::num_put<char> >(a_ios.getloc()).put(
        next, a_ios, fill_char, days
  }; // struct excel_date_facet
 return std::locale(std::locale::classic(), new excel_date_facet());

Can I recommend that the date_facet is changed so that
"put" calls "do_put" which converts to a struct tm and calls a "do_put_tm"

And another question:
I asked a long time ago why the default formatting for dates is "2006-Nov-24"
instead of the current locale formatting. Don't remember the answer now but I
had a look in the TR2 proposal for date_time and saw that it remains that way.
Why should something in a standard don't follow the current locale?

Boost list run by bdawes at, gregod at, cpdaniel at, john at