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