Boost logo

Boost :

From: Martin (adrianm_at_[hidden])
Date: 2005-04-24 03:06:51


> > 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

Both lexical cast and program options uses the global locale. In theory you
can change the date format for these by altering the global locale.
(In practice you don't want to do that in a multithreaded application).

I have asked for program_options to have an imbue method and lexical_cast to
take a locale argument but the authors didn't like the idea (which is sad
because it means I can't use these libraries in my applications).

>
> 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.

time_get contain the functions to parse the "tricky" format elements (e.g. "%
x" and weekday etc) but since there are no time_punct facet you can't control
the behaviour of these functions without replacing the facet.

> 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.

Take a look at the libstd++ implementation of the facets. libstd++ adds a non-
standard __time_punct facet which among other things contains the "real"
format string for "%x", date and time separator etc. This means that
formatting and parsing always uses the same format (it is ofcourse still
possible to create formats that can't be parsed correctly).

Dinkumware choosed another way. They are just passing "%x" to strftime so they
have no idea what the local format looks like. This means that parsing is
done "blindly" and doesn't work very well (e.g. my locale uses '-' as date
separator which isn't support by dinkumware's time_get).

> 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
()).

yes, that is what the standard time_punct facet should have had from start. If
you want boost.date_time in the standard I think you should:

1. Move all format strings into a time_punct facet
2. Update the specification of time_put and time_get to use the time_punct
facet.
3. Add functions to time_put and time_get facets to handle durations, ranges
etc.

(for a non-standard boost.date_time keep the current implementation, otherwise
the user need to add 3 facets to the locale)

> //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);
This is actually implementation defined behaviour since streams are allowed to
cache values returned from facets. In this case you are doing the
implementation of operator ">>" so you are safe (but don't alter a num_punct
facet present in a stream).


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