summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--test/ruby/test_time.rb18
-rw-r--r--time.c14
3 files changed, 30 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index fe2b671659..1b160c8e9e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-03-27 Tanaka Akira <akr@fsij.org>
+
+ * time.c: fix previos commit.
+
Sat Mar 27 23:17:52 2010 Tanaka Akira <akr@fsij.org>
* time.c: use 64bit arithmetic even on platforms with 32bit VALUE.
diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb
index 6ccac25553..5543951778 100644
--- a/test/ruby/test_time.rb
+++ b/test/ruby/test_time.rb
@@ -162,6 +162,16 @@ class TestTime < Test::Unit::TestCase
assert_equal(999999998, Time.at(-14e-10).nsec)
assert_equal(999999998, Time.at(-16e-10).nsec)
end
+
+ t = Time.at(-4611686019).utc
+ assert_equal(1823, t.year)
+
+ t = Time.at(4611686018, 999999).utc
+ assert_equal(2116, t.year)
+ assert_equal("0.999999".to_r, t.subsec)
+
+ t = Time.at(2**40 + "1/3".to_r, 9999999999999).utc
+ assert_equal(36812, t.year)
end
def test_at2
@@ -287,6 +297,9 @@ class TestTime < Test::Unit::TestCase
t = Time.local(2000)
assert_equal(t.gmt_offset, T2000 - t)
+
+ assert_equal(-4427700000, Time.utc(-4427700000,12,1).year)
+ assert_equal(-2**30+10, Time.utc(-2**30+10,1,1).year)
end
def test_time_interval
@@ -407,6 +420,11 @@ class TestTime < Test::Unit::TestCase
assert_equal(Rational(1,3), (t0 + SimpleDelegator.new(Rational(4,3))).subsec)
end
+ def test_minus
+ t = Time.at(-4611686018).utc - 100
+ assert_equal(1823, t.year)
+ end
+
def test_readers
assert_equal(0, T2000.sec)
assert_equal(0, T2000.min)
diff --git a/time.c b/time.c
index 9ac1ec3091..96f995b329 100644
--- a/time.c
+++ b/time.c
@@ -122,11 +122,12 @@ xv2w(VALUE xv) {
int64_t i = 0;
while (len)
i = (i << sizeof(BDIGIT)*CHAR_BIT) | ds[--len];
- TIMEW_SETVAL(w, INT64toFIXTV(i));
+ if (FIXTVABLE(i))
+ TIMEW_SETVAL(w, INT64toFIXTV(i));
}
}
else {
- if (ds[len-1] <= ((BDIGIT)1 << (sizeof(BDIGIT)*CHAR_BIT-2))) {
+ if (ds[len-1] < ((BDIGIT)1 << (sizeof(BDIGIT)*CHAR_BIT-2))) {
int64_t i = 0;
while (len)
i = (i << sizeof(BDIGIT)*CHAR_BIT) | ds[--len];
@@ -616,7 +617,7 @@ timegmw_noleapsecond(struct vtm *vtm)
int year_mod400;
int yday = vtm->mday;
long days_in400;
- VALUE ret;
+ VALUE vdays, ret;
timew_t wret;
year1900 = sub(vtm->year, INT2FIX(1900));
@@ -643,9 +644,10 @@ timegmw_noleapsecond(struct vtm *vtm)
+ DIV(year_mod400 - 69, 4)
- DIV(year_mod400 - 1, 100)
+ (year_mod400 + 299) / 400;
- ret = add(ret, mul(LONG2NUM(days_in400), INT2FIX(86400)));
- ret = add(ret, mul(q400, INT2FIX(97*86400)));
- ret = add(ret, mul(year1900, INT2FIX(365*86400)));
+ vdays = LONG2NUM(days_in400);
+ vdays = add(vdays, mul(q400, INT2FIX(97)));
+ vdays = add(vdays, mul(year1900, INT2FIX(365)));
+ ret = add(ret, mul(vdays, INT2FIX(86400)));
wret = wadd(rb_time_magnify(ret), xv2w(vtm->subsecx));
return wret;