ふなばです。
ダテクラスを書いていて、あらためて気がついた lib/date.rb の疑問点です。
`-' で period が <= 0 にならないようにチェックしていますが、`-' で必要な
らば、`+' でも必要なはずだと思います (増加するばかりとは限らない)。
ダテクラスのテストのついでに、lib/date.rb のテストもしてみました。
lib/date.rb は暦計算を間違えることがあります。1601年1月1日から2000年12月
31日まで (146097日) 日付の対応を確認したところ、そのうちの7867日で誤りが
みつかりました。
require 'date'
x = Date.new(1752, 12, 31)
x += 1
puts x # => "Fri, Jan 1 1753"
x -= 1
puts x # => "Mon, Jan 11 1753"
これは `-' がよくないわけではなくて、暦計算そのものがよくないわけです。
で、あまり自信がないのですが、ちょろっと手を入れてみました。一応、これ
でうまくいっているようです。でも、本当に確かなのか、わかりませんから、
信用しないでください。
--- date.rb.orig Wed Feb 18 11:31:19 1998
+++ date.rb Mon Mar 2 19:11:47 1998
@@ -109,6 +109,9 @@
else
raise TypeError, "Illegal type. (Integer or Date)"
end
+ if d <= 0
+ raise ArgumentError, "argument out of range. (self > other)"
+ end
return Date.at(d)
end
@@ -146,11 +149,7 @@
end
def leapyear?
- if Date.leapyear(@year) == 1
- return FALSE
- else
- return TRUE
- end
+ Date.leapyear(@year) != 1
end
def _check_date
@@ -221,10 +220,10 @@
p += dl[mm]
end
p += (y - 1) * 365 + ((y - 1) / 4.0).to_i
- if (y - 1) > 1752
- p -= ((y - 1 - 1752) / 100.0).to_i
- p += ((y - 1 - 1752) / 400.0).to_i
- p -= (14 - 3)
+ if y > 1752
+ p -= ((y - 1) / 100.0).to_i
+ p += ((y - 1) / 400.0).to_i
+ p += 2
elsif y == 1752 && m == 9 && d >= 14 && d <= 30
p -= (14 - 3)
end
#ついでですが、マニュアルの Time#gm で month の記述が修正されていないよう
#です。
--Tadayoshi Funaba