| Summary: | strptime(3) '%C' conversion incorrect | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | Crist J. Clark <cjc> | ||||
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | CC: | kevin.ruddy | ||||
| Priority: | Normal | ||||||
| Version: | 3.3-STABLE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
On Thu, 11 Nov 1999 00:43:29 EST, "Crist J. Clark" wrote: > However, the '%C' conversion does not work as described in strftime(3) > (which strptime(3) references as containing the key for the > conversions), nor does a simple 'date +%C' return what the actual > strptime(3) function wants. I think that strptime(3) does behave as expected. I think you're assuming too much. > struct tm tm; > > strptime("19","%C",&tm); > > printf("%d\n",tm.tm_year); You can't expect tm_year to contain anything sensible after your call to strptime, because you haven't given it enough information. Try using it in conjunction with %g and you'll get sensible results. Ciao, Sheldon. Sheldon Hearn wrote, > On Thu, 11 Nov 1999 00:43:29 EST, "Crist J. Clark" wrote: > > > However, the '%C' conversion does not work as described in strftime(3) > > (which strptime(3) references as containing the key for the > > conversions), nor does a simple 'date +%C' return what the actual > > strptime(3) function wants. > > I think that strptime(3) does behave as expected. I think you're > assuming too much. No, it does not. In /usr/src/lib/libc/stdtime/strptime.c we have, case 'C': buf = _strptime(buf, Locale->date_fmt, tm); if (buf == 0) return 0; break; And in stdftime.c we have, case 'C': /* ** %C used to do a... ** _fmt("%a %b %e %X %Y", t); ** ...whereas now POSIX 1003.2 calls for ** something completely different. ** (ado, 5/24/93) */ pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, "%02d", pt, ptlim); continue; Which quite clearly points out theat strptime(3) is using something like the _old_ (pre-93!) definition of '%C' contrary to POSIX, strftime(3) documentation and functionality, and date(1) functionality. stdptime.c is clearly wrong. > > struct tm tm; > > > > strptime("19","%C",&tm); > > > > printf("%d\n",tm.tm_year); > > You can't expect tm_year to contain anything sensible after your call to > strptime, because you haven't given it enough information. Try using it > in conjunction with %g and you'll get sensible results. Well, I would go to show that using the existing '%C' combined with '%g' would not work either, but ran into a little problem. '%g' (or '%G') is not defined at all in strptime.c. However, I one might think "%C %y" would accomplish what you would like. Unfortunately, '%y' _sets_ tm.tm_year, so even if '%C' did what it was supposed to, the result would be wiped out. So, now that I look at it more closely, since '%y' cannot be used in combination with '%C' anyway, '%C' is pretty useless even if it works. I also now realize if you have a date like, "10/20/50," there is no way to tell strptime() that you mean 1950 and _not_ 2050. You'd have to fix tm.tm_year yourself. It actually might be best to simply elimiate '%C' from strptime.c altogether (since the current implementation is incorrect and a fix is almost useless even if it works) and make note of some of these issues on the manpages. -- Crist J. Clark cjclark@home.com Hi there! Can you let me know whether rev 1.12 of strptime.c fixed the problem. I haven't looked any deeper than the commit message. :-) Thanks, Sheldon. State Changed From-To: open->analyzed Fixed in -current by different way State Changed From-To: analyzed->closed fixed long ago |
The strptime(3) function fills a time 'tm structure' from a user's string using a format also provided by the user. However, the '%C' conversion does not work as described in strftime(3) (which strptime(3) references as containing the key for the conversions), nor does a simple 'date +%C' return what the actual strptime(3) function wants. Fix: I actually looked at strptime(3) to fix something else (it can't read formats that run together, e.g "%y%j%H%M%S"), when I noticed the way it handles '%C' is contradictory to the manpages and date(1)'s operation. It was a quick fix. Patch: How-To-Repeat: A C fragment, struct tm tm; strptime("19","%C",&tm); printf("%d\n",tm.tm_year); Which fails using the existing code. It should return, 0 Or of we were to substitute "20" for "19", 100