aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2019-12-17 10:31:20 +0900
committerYusuke Endoh <mame@ruby-lang.org>2019-12-17 10:36:20 +0900
commitd6a2bce64a7fa1099e507e1d36b5f1533f42f60f (patch)
treea4fec2936059a9fab247890489835b8a1eda1f15
parent5da4a310ccf7f4131c1814a2c9279a5682777f1b (diff)
downloadruby-d6a2bce64a7fa1099e507e1d36b5f1533f42f60f.tar.gz
time.c (find_time_t): fix round-to-zero bug
`find_time_t` did not work correctly for year older than the Epoch because it used C's integer division (which rounds negative to zero). For example, `TIme.new(1933)` returned a wrong time whose year is 1922 in Asia/Kuala_Lumpur because there is no 00:00:00 1st Jan. 1933 in the time zone. ``` $ TZ=Asia/Kuala_Lumpur ruby -e 'p Time.new(1933)' 1932-12-31 00:00:00 +0700 ``` This change fixes the issue by using `DIV` macro instead of `/`. Now `Time.new(1933)` returns a time in 1933. ``` $ TZ=Asia/Kuala_Lumpur ruby -e 'p Time.new(1933)' 1933-01-01 00:20:00 +0720 ``` [Bug #16159]
-rw-r--r--time.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/time.c b/time.c
index 25b843e405..ef8a995da4 100644
--- a/time.c
+++ b/time.c
@@ -3365,12 +3365,12 @@ find_time_t(struct tm *tptr, int utc_p, time_t *tp)
*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) +
+ DIV((tptr->tm_year-69), 4) -
+ DIV((tptr->tm_year-1), 100) +
+ DIV((tptr->tm_year+299), 400) -
+ DIV((tm_lo.tm_year-69), 4) +
+ DIV((tm_lo.tm_year-1), 100) -
+ DIV((tm_lo.tm_year+299), 400) +
tptr_tm_yday -
tm_lo.tm_yday) * 86400 +
(tptr->tm_hour - tm_lo.tm_hour) * 3600 +