Martin Sebor wrote: > >The C and C++ standards only specify the requirements on the "C" >locale and leave the localized behavior unspecified. So pretty >much anything goes. >
I don't know how you can say that with a straight face. The C++ standard says that time_put<>::put() treats the format string like strftime(). The C and POSIX specifications both define the output for strftime() for each of the required format specifiers. The numeric values are pretty strictly specified, and the non-numeric ones [%b as an example] are supposed to be defined by the specified locales LC_TIME category. It seems pretty well defined, it is just through three levels of indirection. It makes sense to not define the behavior for all locales explicitly in the C standard, since locale definition files can be created by the user, and the system provided ones could be modified or removed. > >There are some ground rules but I suspect >you won't be able to tease the requirement on swallowing leading >space for the %e directive out of them. > I wouldn't think so, but I might not need to. See below... > >> >> Well, there's the problem right there. The standard requires that the >> time_put<> facet format its output according to the POSIX function >> strftime(), with the option for supporting extensions. It makes no >> indication that the time_get<> facet should read data in >such a way as >> to be compatible with strptime(). The only thing I see that says >> anything about the format expecte by time_get<> is here... >[...] >> > >Right. Pretty vague. > I guess you could interpret that as vague. I mean they don't explicitly say you can't try to emulate strptime(). Of course they don't explicitly say you should attempt to either. They do, on the other hand, say that the put() should behave consistently with strftime(), and that get_*() should be able to read the output of put() for a given format. >> >>> Absolutely. The docs for POSIX strftime()... >>> [...] >> >> So strftime() isn't even compatible with strptime() when it >> comes to '%e'. > >Hmm. That seems like a bug in POSIX then, unless we're missing >something. You might want to create a POSIX-only test case to >verify this and if I'm right open a discussion on the Austin >Group list (http://www.opengroup.org/austin/lists.html). > Yeah, I've made a testcase using strptime(), but it passes on most environments I've tested. Source... #include <stdio.h> #include <time.h> #include <assert.h> #include <string.h> int main (int argc, char* argv []) { const char* fmt = "-%H:%M:%S-%m/%e/%Y-"; const char* buf = "-01:02:03-04/ 5/1906 -"; struct tm r; memset (&r, 0, sizeof (r)); strptime (buf, fmt, &r); fprintf (stderr, "%%H=%d %%M=%d %%S=%d %%m=%d %%e=%d %%Y=%d\n", r.tm_hour, r.tm_min, r.tm_sec, r.tm_mon, r.tm_mday, r.tm_year); assert (1 == r.tm_hour); // [01,12] assert (2 == r.tm_min); // [00,59] assert (3 == r.tm_sec); // [00,61] assert (3 == r.tm_mon); // [00,11] assert (5 == r.tm_mday); // [01,31] assert (6 == r.tm_year); // [00,99] return 0; } The strptime() function is clearly skipping leading whitespace with the '%e' flag on those platforms that allow this test to pass. Here is a quick test matrix Pass | Fail | ----+-------+-------+ Linux26/gcc346 | X | | Solaris58/SunPro53 | X | | HP-UX11/ACC373 | | X | DEC5.1/C++71 | X | | ----+-------+-------+ Win32/VC8 | no strptime() | >> >My approach would be to detect locales with this >problem and avoid using them. The test also doesn't need to >be exhaustive, at least not in this iteration. I think >exercising just the most common patterns should be good enough >(although %X is pretty common :) Yes, I could verify the locale doesn't use '%e' to represent weekdays for the time being. > >Martin >