summaryrefslogtreecommitdiff
path: root/time.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-07-05 15:11:27 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-07-05 15:11:27 +0000
commitb5279bb551daae4ad7b4585864b017c25c9f8d5e (patch)
tree15a1588c72095859192983389b971d290af0b7a8 /time.c
parentb50cc1fe570b9eac594d5b8d8bbdde0bce5d5587 (diff)
* time.c (find_time_t): fix Time.local(2009,2,31) failure on 64bit
time_t environment. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23962 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'time.c')
-rw-r--r--time.c68
1 files changed, 58 insertions, 10 deletions
diff --git a/time.c b/time.c
index 6775e821f4..d349009dcf 100644
--- a/time.c
+++ b/time.c
@@ -1887,7 +1887,7 @@ static const char *
find_time_t(struct tm *tptr, int utc_p, time_t *tp)
{
time_t guess, guess0, guess_lo, guess_hi;
- struct tm *tm, tm_lo, tm_hi;
+ struct tm *tm, tm0, tm_lo, tm_hi;
int d;
int find_dst;
struct tm result;
@@ -1895,19 +1895,67 @@ find_time_t(struct tm *tptr, int utc_p, time_t *tp)
#define GUESS(p) (DEBUG_FIND_TIME_NUMGUESS_INC (utc_p ? gmtime_with_leapsecond(p, &result) : LOCALTIME(p, result)))
+ guess_lo = TIMET_MIN;
+ guess_hi = TIMET_MAX;
+
find_dst = 0 < tptr->tm_isdst;
-#ifdef NEGATIVE_TIME_T
- guess_lo = (time_t)~((unsigned_time_t)~(time_t)0 >> 1);
-#else
- guess_lo = 0;
-#endif
- guess_hi = ((time_t)-1) < ((time_t)0) ?
- (time_t)((unsigned_time_t)~(time_t)0 >> 1) :
- ~(time_t)0;
+ tm0 = *tptr;
+ if (tm0.tm_mon < 0) {
+ tm0.tm_mon = 0;
+ tm0.tm_mday = 1;
+ tm0.tm_hour = 0;
+ tm0.tm_min = 0;
+ tm0.tm_sec = 0;
+ }
+ else if (11 < tm0.tm_mon) {
+ tm0.tm_mon = 11;
+ tm0.tm_mday = 31;
+ tm0.tm_hour = 23;
+ tm0.tm_min = 59;
+ tm0.tm_sec = 60;
+ }
+ else if (tm0.tm_mday < 1) {
+ tm0.tm_mday = 1;
+ tm0.tm_hour = 0;
+ tm0.tm_min = 0;
+ tm0.tm_sec = 0;
+ }
+ else if ((d = (leap_year_p(1900 + tm0.tm_year) ?
+ leap_year_days_in_month :
+ common_year_days_in_month)[tm0.tm_mon]) < tm0.tm_mday) {
+ tm0.tm_mday = d;
+ tm0.tm_hour = 23;
+ tm0.tm_min = 59;
+ tm0.tm_sec = 60;
+ }
+ else if (tm0.tm_hour < 0) {
+ tm0.tm_hour = 0;
+ tm0.tm_min = 0;
+ tm0.tm_sec = 0;
+ }
+ else if (23 < tm0.tm_hour) {
+ tm0.tm_hour = 23;
+ tm0.tm_min = 59;
+ tm0.tm_sec = 60;
+ }
+ else if (tm0.tm_min < 0) {
+ tm0.tm_min = 0;
+ tm0.tm_sec = 0;
+ }
+ else if (59 < tm0.tm_min) {
+ tm0.tm_min = 59;
+ tm0.tm_sec = 60;
+ }
+ else if (tm0.tm_sec < 0) {
+ tm0.tm_sec = 0;
+ }
+ else if (60 < tm0.tm_sec) {
+ tm0.tm_sec = 60;
+ }
DEBUG_REPORT_GUESSRANGE;
- guess0 = guess = timegm_noleapsecond(tptr);
+ guess0 = guess = timegm_noleapsecond(&tm0);
tm = GUESS(&guess);
if (tm) {
d = tmcmp(tptr, tm);