Boost logo

Boost :

From: Jeff Garland (jeff_at_[hidden])
Date: 2005-04-23 12:07:20


On Sat, 23 Apr 2005 16:00:07 +0000 (UTC), Martin wrote
> > Why not drop facets altogether and use a stream format manipulator instead:
> >
> > std::cout << set_date_format("%Y-%b-%d") << mydate << std::endl;
>
> The problem with manipulators is that you need access to the stream.
> How do you use manipulators with lexical cast and program options?

Good point -- although last I checked you don't have access to the stream for
lexical cast either so I'm not sure this helps :-(

> > You could still have a facet if you really wanted uses to change the
> > *algorithm* used for io, but I guess what I'm trying to say is that:
> >
> > algorithms go in facets.
> > configuration data goes in the iostream object itself.
>
> I'd say that the date format is a localization thing and as such
> belong in a facet. The standard is consistant on keeping
> localization things in facets
>
> However, the standard is broken when it comes to date and time
> issues which makes it difficult.
>
> Normally format specifiers are in one facet (num_punct, money_punct)
> while the actual formatting/parsing occurs in another (num_put/get,
> money_put/get).
>
> For date_time there is no time_punct facet (anyone know why?).

Interesting point. My take on the standard time facet stuff is that it was a
simple solution just built the C standard. It didn't really attempt to extend
the state of the art much...

> The standard only says that time_put formats the date as specifed in
> a strftime format string. It says nothing about where this string
> should come from. Maybe the intention was to allow the date format
> as a modifier but I doubt it since it makes it impossible to
> implement time_get correctly (how do you parse '%x').

Well the input half of the current standard is certainly problematic. While
you can specify an output format for time_put you can't do that for time_get.
    So you can't do round trip i/o using the facet (well ok, you can build a
parser on top of the facet functions, but it's obviously non-semmetric).
There's also no easy way other than creating a locale to replace the strings
used for parsing.

The new Boost date-time allows the user to control all the strings and allows
for semetric i/o based on the format strings. Of course Boost date-time has
other considerations not addressed by the current standard like output of
period and duration types, output of the generator classes, and handling of
special values (not-a-date-time, infinities, etc). I've also tried to
abstract a few of the common formats like iso so you can do common formats
without having to know the actual format strings (date_facet->set_iso_format()).

Jeff

//an input example:
const char* const month_short_names[]={"*jan*","*feb*","*mar*",
                                       "*apr*","*may*","*jun*",
                                       "*jul*","*aug*","*sep*",
                                       "*oct*","*nov*","*dec*"};

std::vector<std::basic_string<char> > short_month_names;

int
main()
{

  using namespace boost::gregorian;

  std::copy(&month_short_names[0],
            &month_short_names[12],
            std::back_inserter(short_month_names));

  //and now for a real trick
  std::istringstream ss("2005 *apr* 01");
  date_input_facet* dif = new date_input_facet("%Y %b %d");
  ss.imbue(std::locale(std::locale::classic(), dif));
  dif->short_month_names(short_month_names);
  date fools;
  ss >> fools;
 
}

 


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk