aboutsummaryrefslogtreecommitdiff
path: root/time
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2004-10-22 22:15:54 +0000
committerRoland McGrath <roland@gnu.org>2004-10-22 22:15:54 +0000
commit7203529423b8ea749b66874b86a038118f8dba00 (patch)
treebc7e29e1fe1b898276aa7cdeb0caededbc4ee51a /time
parentc60a75408e675bbb8b50ce894d000f645a8bdff7 (diff)
downloadglibc-7203529423b8ea749b66874b86a038118f8dba00.zip
glibc-7203529423b8ea749b66874b86a038118f8dba00.tar.gz
glibc-7203529423b8ea749b66874b86a038118f8dba00.tar.bz2
[BZ #469] Imported from gnulib.
* time/mktime.c (__isleap): Remove; all uses replaced by: (leapyear): New function, which avoids overflow by not adding 1900 to year before testing whether it is a leap year.
Diffstat (limited to 'time')
-rw-r--r--time/mktime.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/time/mktime.c b/time/mktime.c
index 65168bf..1acad26 100644
--- a/time/mktime.c
+++ b/time/mktime.c
@@ -75,12 +75,17 @@ verify (right_shift_propagates_sign, -1 >> 1 == -1);
#define TM_YEAR_BASE 1900
verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
-#ifndef __isleap
-/* Nonzero if YEAR is a leap year (every 4 years,
- except every 100th isn't, and every 400th is). */
-# define __isleap(year) \
- ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
-#endif
+/* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */
+static inline int
+leapyear (int year)
+{
+ /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
+ Also, work even if YEAR is negative. */
+ return
+ ((year & 3) == 0
+ && (year % 100 != 0
+ || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3)));
+}
/* How many days come before each month (0-12). */
#ifndef _LIBC
@@ -234,7 +239,7 @@ __mktime_internal (struct tm *tp,
/* Calculate day of year from year, month, and day of month.
The result need not be in range. */
- int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
+ int yday = ((__mon_yday[leapyear (year)]
[mon_remainder + 12 * negative_mon_remainder])
+ mday - 1);