diff --git a/newlib/libc/time/gmtime_r.c b/newlib/libc/time/gmtime_r.c index 6475df3ba..379e8c26b 100644 --- a/newlib/libc/time/gmtime_r.c +++ b/newlib/libc/time/gmtime_r.c @@ -50,9 +50,9 @@ _DEFUN (gmtime_r, (tim_p, res), _CONST time_t *__restrict tim_p _AND struct tm *__restrict res) { - long days, rem; + time_t days, rem, year; _CONST time_t lcltime = *tim_p; - int era, weekday, year; + int era, weekday; unsigned erayear, yearday, month, day; unsigned long eraday; @@ -81,12 +81,12 @@ _DEFUN (gmtime_r, (tim_p, res), era = (days >= 0 ? days : days - (DAYS_PER_ERA - 1)) / DAYS_PER_ERA; eraday = days - era * DAYS_PER_ERA; /* [0, 146096] */ erayear = (eraday - eraday / (DAYS_PER_4_YEARS - 1) + eraday / DAYS_PER_CENTURY - - eraday / (DAYS_PER_ERA - 1)) / 365; /* [0, 399] */ + eraday / (DAYS_PER_ERA - 1)) / DAYS_PER_YEAR; /* [0, 399] */ yearday = eraday - (DAYS_PER_YEAR * erayear + erayear / 4 - erayear / 100); /* [0, 365] */ month = (5 * yearday + 2) / 153; /* [0, 11] */ day = yearday - (153 * month + 2) / 5 + 1; /* [1, 31] */ month += month < 10 ? 2 : -10; - year = ADJUSTED_EPOCH_YEAR + erayear + era * YEARS_PER_ERA + (month <= 1); + year = ADJUSTED_EPOCH_YEAR + erayear + (time_t)era * YEARS_PER_ERA + (month <= 1); res->tm_yday = yearday >= DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY ? yearday - (DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY) : diff --git a/newlib/libc/time/lcltime_r.c b/newlib/libc/time/lcltime_r.c index 3342e9906..56247350d 100644 --- a/newlib/libc/time/lcltime_r.c +++ b/newlib/libc/time/lcltime_r.c @@ -22,13 +22,13 @@ _DEFUN (localtime_r, (tim_p, res), { long offset; int hours, mins, secs; - int year; + time_t year; __tzinfo_type *_CONST tz = __gettzinfo (); _CONST int *ip; res = gmtime_r (tim_p, res); - year = res->tm_year + YEAR_BASE; + year = (time_t)(res->tm_year) + YEAR_BASE; ip = __month_lengths[isleap(year)]; TZ_LOCK; @@ -85,7 +85,7 @@ _DEFUN (localtime_r, (tim_p, res), { ++res->tm_yday; ++res->tm_wday; - if (res->tm_wday > 6) + if (res->tm_wday >= DAYSPERWEEK) res->tm_wday = 0; ++res->tm_mday; res->tm_hour -= HOURSPERDAY; @@ -93,7 +93,7 @@ _DEFUN (localtime_r, (tim_p, res), { res->tm_mday -= ip[res->tm_mon]; res->tm_mon += 1; - if (res->tm_mon == 12) + if (res->tm_mon == MONSPERYEAR) { res->tm_mon = 0; res->tm_year += 1; @@ -106,17 +106,17 @@ _DEFUN (localtime_r, (tim_p, res), res->tm_yday -= 1; res->tm_wday -= 1; if (res->tm_wday < 0) - res->tm_wday = 6; + res->tm_wday = DAYSPERWEEK - 1; res->tm_mday -= 1; - res->tm_hour += 24; + res->tm_hour += HOURSPERDAY; if (res->tm_mday == 0) { res->tm_mon -= 1; if (res->tm_mon < 0) { - res->tm_mon = 11; + res->tm_mon = MONSPERYEAR - 1; res->tm_year -= 1; - res->tm_yday = 364 + isleap(res->tm_year + YEAR_BASE); + res->tm_yday = 364 + isleap((time_t)(res->tm_year) + YEAR_BASE); } res->tm_mday = ip[res->tm_mon]; } diff --git a/newlib/libc/time/local.h b/newlib/libc/time/local.h index af5793af9..1261496d0 100644 --- a/newlib/libc/time/local.h +++ b/newlib/libc/time/local.h @@ -19,7 +19,7 @@ #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) -int _EXFUN (__tzcalc_limits, (int __year)); +int _EXFUN (__tzcalc_limits, (time_t __year)); extern _CONST int __month_lengths[2][MONSPERYEAR]; diff --git a/newlib/libc/time/mktime.c b/newlib/libc/time/mktime.c index 44c0257f7..f01037b97 100644 --- a/newlib/libc/time/mktime.c +++ b/newlib/libc/time/mktime.c @@ -51,10 +51,6 @@ ANSI C requires <>. #include #include "local.h" -#define _SEC_IN_MINUTE 60L -#define _SEC_IN_HOUR 3600L -#define _SEC_IN_DAY 86400L - static _CONST int DAYS_IN_MONTH[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; @@ -63,8 +59,7 @@ static _CONST int DAYS_IN_MONTH[12] = static _CONST int _DAYS_BEFORE_MONTH[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; -#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0)) -#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365) +#define _DAYS_IN_YEAR(year) (isleap((year) + YEAR_BASE) ? 366 : 365) static void _DEFUN(validate_structure, (tim_p), @@ -74,46 +69,46 @@ _DEFUN(validate_structure, (tim_p), int days_in_feb = 28; /* calculate time & date to account for out of range values */ - if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59) + if (tim_p->tm_sec < 0 || tim_p->tm_sec >= SECSPERMIN) { - res = div (tim_p->tm_sec, 60); + res = div (tim_p->tm_sec, SECSPERMIN); tim_p->tm_min += res.quot; if ((tim_p->tm_sec = res.rem) < 0) { - tim_p->tm_sec += 60; + tim_p->tm_sec += SECSPERMIN; --tim_p->tm_min; } } - if (tim_p->tm_min < 0 || tim_p->tm_min > 59) + if (tim_p->tm_min < 0 || tim_p->tm_min >= MINSPERHOUR) { - res = div (tim_p->tm_min, 60); + res = div (tim_p->tm_min, MINSPERHOUR); tim_p->tm_hour += res.quot; if ((tim_p->tm_min = res.rem) < 0) { - tim_p->tm_min += 60; + tim_p->tm_min += MINSPERHOUR; --tim_p->tm_hour; } } - if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23) + if (tim_p->tm_hour < 0 || tim_p->tm_hour >= HOURSPERDAY) { - res = div (tim_p->tm_hour, 24); + res = div (tim_p->tm_hour, HOURSPERDAY); tim_p->tm_mday += res.quot; if ((tim_p->tm_hour = res.rem) < 0) { - tim_p->tm_hour += 24; + tim_p->tm_hour += HOURSPERDAY; --tim_p->tm_mday; } } - if (tim_p->tm_mon < 0 || tim_p->tm_mon > 11) + if (tim_p->tm_mon < 0 || tim_p->tm_mon >= MONSPERYEAR) { - res = div (tim_p->tm_mon, 12); + res = div (tim_p->tm_mon, MONSPERYEAR); tim_p->tm_year += res.quot; if ((tim_p->tm_mon = res.rem) < 0) { - tim_p->tm_mon += 12; + tim_p->tm_mon += MONSPERYEAR; --tim_p->tm_year; } } @@ -128,7 +123,7 @@ _DEFUN(validate_structure, (tim_p), if (--tim_p->tm_mon == -1) { tim_p->tm_year--; - tim_p->tm_mon = 11; + tim_p->tm_mon = MONSPERYEAR - 1; days_in_feb = ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? 29 : 28); @@ -141,7 +136,7 @@ _DEFUN(validate_structure, (tim_p), while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon)) { tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon); - if (++tim_p->tm_mon == 12) + if (++tim_p->tm_mon == MONSPERYEAR) { tim_p->tm_year++; tim_p->tm_mon = 0; @@ -158,16 +153,17 @@ _DEFUN(mktime, (tim_p), struct tm *tim_p) { time_t tim = 0; - long days = 0; - int year, isdst=0; + time_t days = 0; + time_t year; + int isdst=0; __tzinfo_type *tz = __gettzinfo (); /* validate structure */ validate_structure (tim_p); /* compute hours, minutes, seconds */ - tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) + - (tim_p->tm_hour * _SEC_IN_HOUR); + tim += tim_p->tm_sec + (tim_p->tm_min * SECSPERMIN) + + (tim_p->tm_hour * SECSPERHOUR); /* compute days in year */ days += tim_p->tm_mday - 1; @@ -178,9 +174,6 @@ _DEFUN(mktime, (tim_p), /* compute day of the year */ tim_p->tm_yday = days; - if (tim_p->tm_year > 10000 || tim_p->tm_year < -10000) - return (time_t) -1; - /* compute days in other years */ if ((year = tim_p->tm_year) > 70) { @@ -195,7 +188,7 @@ _DEFUN(mktime, (tim_p), } /* compute total seconds */ - tim += (days * _SEC_IN_DAY); + tim += (days * SECSPERDAY); TZ_LOCK; @@ -204,7 +197,7 @@ _DEFUN(mktime, (tim_p), if (_daylight) { int tm_isdst; - int y = tim_p->tm_year + YEAR_BASE; + time_t y = tim_p->tm_year + YEAR_BASE; /* Convert user positive into 1 */ tm_isdst = tim_p->tm_isdst > 0 ? 1 : tim_p->tm_isdst; isdst = tm_isdst; @@ -236,7 +229,7 @@ _DEFUN(mktime, (tim_p), time zone offsets, depending on which way the user got it wrong. The diff is typically one hour, or 3600 seconds, and should fit in a 16-bit int, even though offset - is a long to accomodate 12 hours. */ + is a long to accomodate 12+ hours. */ int diff = (int) (tz->__tzrule[0].offset - tz->__tzrule[1].offset); if (!isdst) @@ -261,7 +254,7 @@ _DEFUN(mktime, (tim_p), tim_p->tm_yday = _DAYS_IN_YEAR(year) - 1; } else { mday = _DAYS_IN_YEAR(year); - if (tim_p->tm_yday > (mday - 1)) + if (tim_p->tm_yday >= mday) tim_p->tm_yday -= mday; } } @@ -282,8 +275,8 @@ _DEFUN(mktime, (tim_p), tim_p->tm_isdst = isdst; /* compute day of the week */ - if ((tim_p->tm_wday = (days + 4) % 7) < 0) - tim_p->tm_wday += 7; + if ((tim_p->tm_wday = (days + EPOCH_WDAY) % DAYSPERWEEK) < 0) + tim_p->tm_wday += DAYSPERWEEK; return tim; } diff --git a/newlib/libc/time/strftime.c b/newlib/libc/time/strftime.c index 382318047..b99b0671c 100644 --- a/newlib/libc/time/strftime.c +++ b/newlib/libc/time/strftime.c @@ -360,7 +360,7 @@ _DEFUN (iso_year_adjust, (tim_p), _CONST struct tm *tim_p) { /* Account for fact that tm_year==0 is year 1900. */ - int leap = isleap (tim_p->tm_year + (YEAR_BASE + int leap = isleap ((time_t)(tim_p->tm_year) + (YEAR_BASE - (tim_p->tm_year < 0 ? 0 : 2000))); /* Pack the yday, wday, and leap year into a single int since there are so @@ -872,7 +872,7 @@ recurse: int neg = tim_p->tm_year < -YEAR_BASE; int century = tim_p->tm_year >= 0 ? tim_p->tm_year / 100 + YEAR_BASE / 100 - : abs (tim_p->tm_year + YEAR_BASE) / 100; + : llabs ((time_t)(tim_p->tm_year) + YEAR_BASE) / 100; if (pad) /* '0' or '+' */ { fmt = CQ("%s%0.*d"); @@ -922,7 +922,7 @@ recurse: CQ("%.2d/%.2d/%.2d"), tim_p->tm_mon + 1, tim_p->tm_mday, tim_p->tm_year >= 0 ? tim_p->tm_year % 100 - : abs (tim_p->tm_year + YEAR_BASE) % 100); + : llabs ((time_t)(tim_p->tm_year) + YEAR_BASE) % 100); CHECK_LENGTH (); break; case CQ('F'): @@ -961,7 +961,7 @@ recurse: { int adjust = iso_year_adjust (tim_p); int year = tim_p->tm_year >= 0 ? tim_p->tm_year % 100 - : abs (tim_p->tm_year + YEAR_BASE) % 100; + : llabs ((time_t)(tim_p->tm_year) + YEAR_BASE) % 100; if (adjust < 0 && tim_p->tm_year <= -YEAR_BASE) adjust = 1; else if (adjust > 0 && tim_p->tm_year < -YEAR_BASE) @@ -980,9 +980,9 @@ recurse: int adjust = iso_year_adjust (tim_p); int century = tim_p->tm_year >= 0 ? tim_p->tm_year / 100 + YEAR_BASE / 100 - : abs (tim_p->tm_year + YEAR_BASE) / 100; + : llabs ((time_t)(tim_p->tm_year) + YEAR_BASE) / 100; int year = tim_p->tm_year >= 0 ? tim_p->tm_year % 100 - : abs (tim_p->tm_year + YEAR_BASE) % 100; + : llabs ((time_t)(tim_p->tm_year) + YEAR_BASE) % 100; if (adjust < 0 && tim_p->tm_year <= -YEAR_BASE) sign = adjust = 1; else if (adjust > 0 && sign) @@ -999,8 +999,8 @@ recurse: ++century; } CHAR fmtbuf[10], *fmt = fmtbuf; - /* int potentially overflows, so use unsigned instead. */ - unsigned p_year = century * 100 + year; + /* int potentially overflows, so use time_t instead. */ + time_t p_year = century * 100 + year; if (sign) *fmt++ = CQ('-'); else if (pad == CQ('+') && p_year >= 10000) @@ -1013,8 +1013,8 @@ recurse: *fmt++ = CQ('%'); if (pad) *fmt++ = CQ('0'); - STRCPY (fmt, CQ(".*u")); - len = snprintf (&s[count], maxsize - count, fmtbuf, width, p_year); + STRCPY (fmt, CQ(".*lld")); + len = snprintf (&s[count], maxsize - count, fmtbuf, width, (long long)p_year); if (len < 0 || (count+=len) >= maxsize) return 0; } @@ -1105,31 +1105,7 @@ recurse: CHECK_LENGTH (); break; case CQ('s'): -/* - * From: - * The Open Group Base Specifications Issue 7 - * IEEE Std 1003.1, 2013 Edition - * Copyright (c) 2001-2013 The IEEE and The Open Group - * XBD Base Definitions - * 4. General Concepts - * 4.15 Seconds Since the Epoch - * A value that approximates the number of seconds that have elapsed since the - * Epoch. A Coordinated Universal Time name (specified in terms of seconds - * (tm_sec), minutes (tm_min), hours (tm_hour), days since January 1 of the year - * (tm_yday), and calendar year minus 1900 (tm_year)) is related to a time - * represented as seconds since the Epoch, according to the expression below. - * If the year is <1970 or the value is negative, the relationship is undefined. - * If the year is >=1970 and the value is non-negative, the value is related to a - * Coordinated Universal Time name according to the C-language expression, where - * tm_sec, tm_min, tm_hour, tm_yday, and tm_year are all integer types: - * tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 + - * (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 - - * ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400 - * OR - * ((((tm_year-69)/4 - (tm_year-1)/100 + (tm_year+299)/400 + - * (tm_year-70)*365 + tm_yday)*24 + tm_hour)*60 + tm_min)*60 + tm_sec - */ -/* modified from %z case by hoisting offset outside if block and initializing */ +/* modified from %z case by hoisting offset outside of block and initializing */ { long offset = 0; /* offset < 0 => W of GMT, > 0 => E of GMT: subtract to get UTC */ @@ -1162,13 +1138,40 @@ recurse: #endif TZ_UNLOCK; } +/* + * From: + * The Open Group Base Specifications Issue 7 + * IEEE Std 1003.1, 2013 Edition + * Copyright (c) 2001-2013 The IEEE and The Open Group + * XBD Base Definitions + * 4. General Concepts + * 4.15 Seconds Since the Epoch + * A value that approximates the number of seconds that have elapsed since the + * Epoch. A Coordinated Universal Time name (specified in terms of seconds + * (tm_sec), minutes (tm_min), hours (tm_hour), days since January 1 of the year + * (tm_yday), and calendar year minus 1900 (tm_year)) is related to a time + * represented as seconds since the Epoch, according to the expression below. + * If the year is <1970 or the value is negative, the relationship is undefined. + * If the year is >=1970 and the value is non-negative, the value is related to a + * Coordinated Universal Time name according to the C-language expression, where + * tm_sec, tm_min, tm_hour, tm_yday, and tm_year are all integer types: + * tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 + + * (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 - + * ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400 + * OR + * ((((tm_year-69)/4 - (tm_year-1)/100 + (tm_year+299)/400 + + * (tm_year-70)*365 + tm_yday)*24 + tm_hour)*60 + tm_min)*60 + tm_sec + */ len = snprintf (&s[count], maxsize - count, CQ("%lld"), - (((((long long)tim_p->tm_year - 69)/4 - - (tim_p->tm_year - 1)/100 - + (tim_p->tm_year + 299)/400 - + (tim_p->tm_year - 70)*365 + tim_p->tm_yday)*24 - + tim_p->tm_hour)*60 + tim_p->tm_min)*60 - + tim_p->tm_sec - offset); + (long long)(((( + ((time_t)(tim_p->tm_year) - 70)*365 + + (tim_p->tm_year - 69)/4 + - (tim_p->tm_year - 1)/100 + + ((time_t)(tim_p->tm_year) + 299)/400 + + tim_p->tm_yday)*HOURSPERDAY + + tim_p->tm_hour)*MINSPERHOUR + + tim_p->tm_min)*SECSPERMIN + + tim_p->tm_sec - offset)); CHECK_LENGTH (); } break; @@ -1241,7 +1244,7 @@ recurse: Fri, and also if current year starts on Sat and previous year was leap year. */ week = 52 + (4 >= (wday - tim_p->tm_yday - - isleap (tim_p->tm_year + - isleap ((time_t)(tim_p->tm_year) + (YEAR_BASE - 1 - (tim_p->tm_year < 0 ? 0 : 2000))))); @@ -1295,7 +1298,7 @@ recurse: /* Be careful of both overflow and negative years, thanks to the asymmetric range of years. */ int year = tim_p->tm_year >= 0 ? tim_p->tm_year % 100 - : abs (tim_p->tm_year + YEAR_BASE) % 100; + : llabs ((time_t)(tim_p->tm_year) + YEAR_BASE) % 100; #ifdef _WANT_C99_TIME_FORMATS if (alt != CQ('O') || !*alt_digits || !(len = conv_to_alt_digits (&s[count], maxsize - count, @@ -1319,9 +1322,9 @@ recurse: { CHAR fmtbuf[10], *fmt = fmtbuf; int sign = tim_p->tm_year < -YEAR_BASE; - /* int potentially overflows, so use unsigned instead. */ - register unsigned year = (unsigned) tim_p->tm_year - + (unsigned) YEAR_BASE; + /* int potentially overflows, so use time_t instead. */ + register time_t year = (time_t)(tim_p->tm_year) + + YEAR_BASE; if (sign) { *fmt++ = CQ('-'); @@ -1337,9 +1340,9 @@ recurse: *fmt++ = CQ('%'); if (pad) *fmt++ = CQ('0'); - STRCPY (fmt, CQ(".*u")); + STRCPY (fmt, CQ(".*lld")); len = snprintf (&s[count], maxsize - count, fmtbuf, width, - year); + (long long)year); CHECK_LENGTH (); } break; diff --git a/newlib/libc/time/tzcalc_limits.c b/newlib/libc/time/tzcalc_limits.c index 8a0bda3da..e0be70596 100644 --- a/newlib/libc/time/tzcalc_limits.c +++ b/newlib/libc/time/tzcalc_limits.c @@ -12,9 +12,9 @@ int _DEFUN (__tzcalc_limits, (year), - int year) + time_t year) { - int days, year_days, years; + time_t days, year_days, years; int i, j; __tzinfo_type *_CONST tz = __gettzinfo ();