Strftime's %C and %y formats versus wide-ranging tm_year values
Ken Pizzini
tz. at explicate.org
Thu Oct 7 00:36:07 UTC 2004
On Wed, Oct 06, 2004 at 04:12:46PM -0700, Paul Eggert wrote:
> OK, here's a proposed patch to the tz code. It is relative to the
> latest published code on elsie. It incorporates most of Arthur's
> patch circulated yesterday, except it addresses the issues I mentioned
> with C99IPMOD, with floating point, and with integer overflow
> checking; the resulting code uses int arithmetic instead of assuming
> that long and double are wider than int.
For the most part, I like it. Two things bother me a little though:
1) I think it's a shame that isleap_sum() needs the compiler to
do a % more than isleap() does, but 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".)
Not a big deal, but I felt a need to mention it in case someone
else does have a bright idea.
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: one which includes basic #define's such as
isleap(), TM_YEAR_BASE, and SECSPERMIN (all conditionalized as
zdump.c currently does), and the other which contains the more
internals-specific definitions of tzcode.h. Attached is a
patch, relative to Paul's most recent patch, which does this.
--Ken Pizzini
-------------- next part --------------
diff -Nu orig/caldefs.h caldefs.h
--- orig/caldefs.h 1969-12-31 16:00:00.000000000 -0800
+++ caldefs.h 2004-10-06 17:15:41.580409504 -0700
@@ -0,0 +1,72 @@
+/*
+** This file is in the public domain.
+*/
+
+/*
+** These #define's all pertain to the proleptic Gregorian calendar
+** which is pervasively assumed by the C time APIs.
+*/
+
+#ifndef SECSPERMIN
+#define SECSPERMIN 60
+#endif /* !defined SECSPERMIN */
+
+#ifndef MINSPERHOUR
+#define MINSPERHOUR 60
+#endif /* !defined MINSPERHOUR */
+
+#ifndef HOURSPERDAY
+#define HOURSPERDAY 24
+#endif /* !defined HOURSPERDAY */
+
+#ifndef DAYSPERWEEK
+#define DAYSPERWEEK 7
+#endif /* !defined DAYSPERWEEK */
+
+#ifndef DAYSPERNYEAR
+#define DAYSPERNYEAR 365
+#endif /* !defined DAYSPERNYEAR */
+
+#ifndef DAYSPERLYEAR
+#define DAYSPERLYEAR 366
+#endif /* !defined DAYSPERLYEAR */
+
+#ifndef SECSPERHOUR
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+#endif /* !defined SECSPERHOUR */
+
+#ifndef SECSPERDAY
+#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
+#endif /* !defined SECSPERDAY */
+
+#ifndef MONSPERYEAR
+#define MONSPERYEAR 12
+#endif /* !defined MONSPERYEAR */
+
+#ifndef EPOCH_YEAR
+#define EPOCH_YEAR 1970
+#endif /* !defined EPOCH_YEAR */
+
+#ifndef TM_YEAR_BASE
+#define TM_YEAR_BASE 1900
+#endif /* !defined TM_YEAR_BASE */
+
+#ifndef isleap
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
+#endif /* !defined isleap */
+
+#ifndef isleap_sum
+/*
+** Since everything in isleap is modulo 400 (or a factor of 400), we know that
+** isleap(y) == isleap(y % 400)
+** and so
+** isleap(a + b) == isleap((a + b) % 400)
+** or
+** isleap(a + b) == isleap(a % 400 + b % 400)
+** This is true even if % means modulo rather than Fortran remainder
+** (which is allowed by C89 but not C99).
+** We use this to avoid addition overflow problems.
+*/
+
+#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
+#endif /* !defined isleap_sum */
diff -Nu orig/tzfile.h tzfile.h
--- orig/tzfile.h 2004-10-06 16:48:57.089329224 -0700
+++ tzfile.h 2004-10-06 17:16:26.844528312 -0700
@@ -25,6 +25,8 @@
#endif /* !defined NOID */
#endif /* !defined lint */
+#include "caldefs.h"
+
/*
** Information about time zone files.
*/
@@ -120,16 +122,6 @@
#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
#endif /* !defined TZ_MAX_LEAPS */
-#define SECSPERMIN 60
-#define MINSPERHOUR 60
-#define HOURSPERDAY 24
-#define DAYSPERWEEK 7
-#define DAYSPERNYEAR 365
-#define DAYSPERLYEAR 366
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR 12
-
#define TM_SUNDAY 0
#define TM_MONDAY 1
#define TM_TUESDAY 2
@@ -151,27 +143,8 @@
#define TM_NOVEMBER 10
#define TM_DECEMBER 11
-#define TM_YEAR_BASE 1900
-
-#define EPOCH_YEAR 1970
#define EPOCH_WDAY TM_THURSDAY
-#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
-
-/*
-** Since everything in isleap is modulo 400 (or a factor of 400), we know that
-** isleap(y) == isleap(y % 400)
-** and so
-** isleap(a + b) == isleap((a + b) % 400)
-** or
-** isleap(a + b) == isleap(a % 400 + b % 400)
-** This is true even if % means modulo rather than Fortran remainder
-** (which is allowed by C89 but not C99).
-** We use this to avoid addition overflow problems.
-*/
-
-#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
-
#ifndef USG
/*
diff -Nu orig/zdump.c zdump.c
--- orig/zdump.c 2004-10-06 16:48:57.125323752 -0700
+++ zdump.c 2004-10-06 17:17:03.985881968 -0700
@@ -12,6 +12,8 @@
#include "time.h" /* for struct tm */
#include "stdlib.h" /* for exit, malloc, atoi */
+#include "caldefs.h"
+
#ifndef MAX_STRING_LENGTH
#define MAX_STRING_LENGTH 1024
#endif /* !defined MAX_STRING_LENGTH */
@@ -32,54 +34,6 @@
#define EXIT_FAILURE 1
#endif /* !defined EXIT_FAILURE */
-#ifndef SECSPERMIN
-#define SECSPERMIN 60
-#endif /* !defined SECSPERMIN */
-
-#ifndef MINSPERHOUR
-#define MINSPERHOUR 60
-#endif /* !defined MINSPERHOUR */
-
-#ifndef SECSPERHOUR
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#endif /* !defined SECSPERHOUR */
-
-#ifndef HOURSPERDAY
-#define HOURSPERDAY 24
-#endif /* !defined HOURSPERDAY */
-
-#ifndef EPOCH_YEAR
-#define EPOCH_YEAR 1970
-#endif /* !defined EPOCH_YEAR */
-
-#ifndef TM_YEAR_BASE
-#define TM_YEAR_BASE 1900
-#endif /* !defined TM_YEAR_BASE */
-
-#ifndef DAYSPERNYEAR
-#define DAYSPERNYEAR 365
-#endif /* !defined DAYSPERNYEAR */
-
-#ifndef isleap
-#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
-#endif /* !defined isleap */
-
-#ifndef isleap_sum
-/*
-** Since everything in isleap is modulo 400 (or a factor of 400), we know that
-** isleap(y) == isleap(y % 400)
-** and so
-** isleap(a + b) == isleap((a + b) % 400)
-** or
-** isleap(a + b) == isleap(a % 400 + b % 400)
-** This is true even if % means modulo rather than Fortran remainder
-** (which is allowed by C89 but not C99).
-** We use this to avoid addition overflow problems.
-*/
-
-#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
-#endif /* !defined isleap_sum */
-
#if HAVE_GETTEXT
#include "locale.h" /* for setlocale */
#include "libintl.h"
More information about the tz
mailing list