summaryrefslogtreecommitdiff
path: root/time.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-06-09 13:54:03 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-06-09 13:54:03 +0000
commit82e646ea7a0874e762c7c7e335a53fef9a52deb0 (patch)
tree80eb87c2a46ed3ebcaeabb97bd05495385c217a7 /time.c
parent2560c3aaf7d0ba98445780d0634b9e6c6c1a76a8 (diff)
* time.c (find_time_t): always outerpolate from past.
[ruby-core:30672] reported by Benoit Daloze. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@28238 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'time.c')
-rw-r--r--time.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/time.c b/time.c
index be398eb96c..58d8475855 100644
--- a/time.c
+++ b/time.c
@@ -2674,6 +2674,7 @@ find_time_t(struct tm *tptr, int utc_p, time_t *tp)
int find_dst;
struct tm result;
int status;
+ int tptr_tm_yday;
#define GUESS(p) (DEBUG_FIND_TIME_NUMGUESS_INC (utc_p ? gmtime_with_leapsecond(p, &result) : LOCALTIME(p, result)))
@@ -2901,22 +2902,30 @@ find_time_t(struct tm *tptr, int utc_p, time_t *tp)
}
}
/* Given argument has no corresponding time_t. Let's outerpolation. */
- if (tm_lo.tm_year == tptr->tm_year && tm_lo.tm_mon == tptr->tm_mon) {
- *tp = guess_lo +
- (tptr->tm_mday - tm_lo.tm_mday) * 24 * 60 * 60 +
- (tptr->tm_hour - tm_lo.tm_hour) * 60 * 60 +
- (tptr->tm_min - tm_lo.tm_min) * 60 +
- (tptr->tm_sec - tm_lo.tm_sec);
- return NULL;
- }
- else if (tm_hi.tm_year == tptr->tm_year && tm_hi.tm_mon == tptr->tm_mon) {
- *tp = guess_hi +
- (tptr->tm_mday - tm_hi.tm_mday) * 24 * 60 * 60 +
- (tptr->tm_hour - tm_hi.tm_hour) * 60 * 60 +
- (tptr->tm_min - tm_hi.tm_min) * 60 +
- (tptr->tm_sec - tm_hi.tm_sec);
- return NULL;
- }
+ /*
+ * `Seconds Since the Epoch' in SUSv3:
+ * 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
+ */
+
+ tptr_tm_yday = calc_tm_yday(tptr->tm_year, tptr->tm_mon, tptr->tm_mday);
+
+ *tp = guess_lo +
+ ((tptr->tm_year - tm_lo.tm_year) * 365 +
+ ((tptr->tm_year-69)/4) -
+ ((tptr->tm_year-1)/100) +
+ ((tptr->tm_year+299)/400) -
+ ((tm_lo.tm_year-69)/4) +
+ ((tm_lo.tm_year-1)/100) -
+ ((tm_lo.tm_year+299)/400) +
+ tptr_tm_yday -
+ tm_lo.tm_yday) * 86400 +
+ (tptr->tm_hour - tm_lo.tm_hour) * 3600 +
+ (tptr->tm_min - tm_lo.tm_min) * 60 +
+ (tptr->tm_sec - tm_lo.tm_sec);
+
+ return NULL;
out_of_range:
return "time out of range";