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