aboutsummaryrefslogtreecommitdiff
path: root/src/lib/krb5/os/gmt_mktime.c
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2001-03-05 20:48:43 +0000
committerKen Raeburn <raeburn@mit.edu>2001-03-05 20:48:43 +0000
commit56977e69db24b9a3355d8f10fe670b65a0654700 (patch)
tree152685abde2656435408e593e6c1985f0f10543f /src/lib/krb5/os/gmt_mktime.c
parentb16144a37e7a0f57c470dd7b7cfd471e55763143 (diff)
downloadkrb5-56977e69db24b9a3355d8f10fe670b65a0654700.zip
krb5-56977e69db24b9a3355d8f10fe670b65a0654700.tar.gz
krb5-56977e69db24b9a3355d8f10fe670b65a0654700.tar.bz2
* gmt_mktime.c (gmt_mktime): Handle years earlier than 1970.
(main) [TEST_LEAP]: New routine, driver for testing. * Makefile.in (t_mktime): New target. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@13055 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/krb5/os/gmt_mktime.c')
-rw-r--r--src/lib/krb5/os/gmt_mktime.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/src/lib/krb5/os/gmt_mktime.c b/src/lib/krb5/os/gmt_mktime.c
index 1e3eebd..d0053ad 100644
--- a/src/lib/krb5/os/gmt_mktime.c
+++ b/src/lib/krb5/os/gmt_mktime.c
@@ -43,8 +43,18 @@ time_t gmt_mktime(t)
#define assert_time(cnd) if(!(cnd)) return (time_t) -1
- assert_time(t->tm_year>=70);
+ /*
+ * For 32-bit signed time_t centered on 1/1/1970, the range is:
+ * time 0x80000000 -> Fri Dec 13 16:45:52 1901
+ * time 0x7fffffff -> Mon Jan 18 22:14:07 2038
+ *
+ * So years 1901 and 2038 are allowable, but we can't encode all
+ * dates in those years, and we're not doing overflow/underflow
+ * checking for such cases.
+ */
+ assert_time(t->tm_year>=1);
assert_time(t->tm_year<=138);
+
assert_time(t->tm_mon>=0);
assert_time(t->tm_mon<=11);
assert_time(t->tm_mday>=1);
@@ -63,7 +73,10 @@ time_t gmt_mktime(t)
accum *= 365; /* 365 days/normal year */
/* add in leap day for all previous years */
- accum += (t->tm_year - 69) / 4;
+ if (t->tm_year >= 70)
+ accum += (t->tm_year - 69) / 4;
+ else
+ accum -= (72 - t->tm_year) / 4;
/* add in leap day for this year */
if(t->tm_mon >= 2) /* march or later */
if(hasleapday((t->tm_year + 1900))) accum += 1;
@@ -79,3 +92,37 @@ time_t gmt_mktime(t)
return accum;
}
+
+#ifdef TEST_LEAP
+int
+main (int argc, char *argv[])
+{
+ int yr;
+ time_t t;
+ struct tm tm = {
+ .tm_mon = 0, .tm_mday = 1,
+ .tm_hour = 0, .tm_min = 0, .tm_sec = 0,
+ };
+ for (yr = 60; yr <= 104; yr++)
+ {
+ printf ("1/1/%d%c -> ", 1900 + yr, hasleapday((1900+yr)) ? '*' : ' ');
+ tm.tm_year = yr;
+ t = gmt_mktime (&tm);
+ if (t == (time_t) -1)
+ printf ("-1\n");
+ else
+ {
+ long u;
+ if (t % (24 * 60 * 60))
+ printf ("(not integral multiple of days) ");
+ u = t / (24 * 60 * 60);
+ printf ("%3ld*365%+ld\t0x%08lx\n",
+ (long) (u / 365), (long) (u % 365),
+ (long) t);
+ }
+ }
+ t = 0x80000000, printf ("time 0x%lx -> %s", t, ctime (&t));
+ t = 0x7fffffff, printf ("time 0x%lx -> %s", t, ctime (&t));
+ return 0;
+}
+#endif