Strftime's %C and %y formats versus wide-ranging tm_year values
Paul Eggert
eggert at CS.UCLA.EDU
Thu Oct 7 05:20:14 UTC 2004
Ken Pizzini <"tz."@explicate.org> writes:
> 1) I think it's a shame that isleap_sum() needs the compiler to
> do a % more than isleap() does,
Actually, it's two %s more -- and this is assuming the compiler does
common subexpression elimination.
> I certainly don't see any clean way of getting around this.
> (There are ways, but the cures I'm coming up with are all worse
> than the "disease".)
One can optimize the case of isleap_sum(y, TM_YEAR_BASE) a bit
(because TM_YEAR_BASE is known), so that it doesn't do any more %s
than isleap does. But it's a bit messy, and since that case occurs
only in zdump I don't think it's worth the hassle.
> I felt a need to mention it in case someone else does have a
> bright idea.
I think both Arthur and I have noticed the problem. He took a crack
at a simpler approach with the C99IPMOD macro, but that turned out
to be problematic. It'd be nice to come up with a better solution.
Also, the code that looks like this:
decade = timeptr->tm_year / 10 + TM_YEAR_BASE / 10;
y = timeptr->tm_year % 10;
if (y < 0 && 0 < decade) {
y += 10;
decade--;
} else if (decade < 0 && 0 < y) {
y -= 10;
decade++;
}
is repeated in asctime,c and zdump.c, and (in slightly different
form, with a divisor of 100 and where the 2nd value is arbitrary so
the computation is more general) in strftime.c. It might be nice
if that could be packaged up somehow.
> 2) More importantly, I think that there are too many duplicate
> definitions in zdump.c. Given the comment about independence
> at the top of zdump.c this means that or tzfile.h should be broken
> up into two files
Makes sense to me but it's Arthur's call. I suppose the above code
could be factored into the isleap() .h file as well.
PS. I did think of one further minor optimization to the patch I
just submitted. This doesn't affect correctness, just performance
on C99 and most other hosts. Here it is:
===================================================================
RCS file: RCS/asctime.c,v
retrieving revision 2004.3.0.2
retrieving revision 2004.3.0.3
diff -pu -r2004.3.0.2 -r2004.3.0.3
--- asctime.c 2004/10/06 23:03:13 2004.3.0.2
+++ asctime.c 2004/10/07 05:17:19 2004.3.0.3
@@ -101,7 +101,7 @@ char * buf;
if (y < 0 && 0 < decade) {
y += 10;
decade--;
- } else if (decade < 0 && 0 < y) {
+ } else if (-1 % 2 == 1 && decade < 0 && 0 < y) {
y -= 10;
decade++;
}
===================================================================
RCS file: RCS/zdump.c,v
retrieving revision 2004.4.0.3
retrieving revision 2004.4.0.4
diff -pu -r2004.4.0.3 -r2004.4.0.4
--- zdump.c 2004/10/06 23:03:13 2004.4.0.3
+++ zdump.c 2004/10/07 05:17:19 2004.4.0.4
@@ -421,7 +421,7 @@ register const struct tm * timeptr;
if (y < 0 && 0 < decade) {
y += 10;
decade--;
- } else if (decade < 0 && 0 < y) {
+ } else if (-1 % 2 == 1 && decade < 0 && 0 < y) {
y -= 10;
decade++;
}
More information about the tz
mailing list