[前][次][番号順一覧][スレッド一覧]

ruby-changes:59283

From: Yusuke <ko1@a...>
Date: Tue, 17 Dec 2019 10:36:39 +0900 (JST)
Subject: [ruby-changes:59283] d6a2bce64a (master): time.c (find_time_t): fix round-to-zero bug

https://git.ruby-lang.org/ruby.git/commit/?id=d6a2bce64a

From d6a2bce64a7fa1099e507e1d36b5f1533f42f60f Mon Sep 17 00:00:00 2001
From: Yusuke Endoh <mame@r...>
Date: Tue, 17 Dec 2019 10:31:20 +0900
Subject: 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]

diff --git a/time.c b/time.c
index 25b843e..ef8a995 100644
--- a/time.c
+++ b/time.c
@@ -3365,12 +3365,12 @@ find_time_t(struct tm *tptr, int utc_p, time_t *tp) https://github.com/ruby/ruby/blob/trunk/time.c#L3365
 
     *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 +
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]