Project

General

Profile

Actions

Bug #3795

closed

Date._valid_civil? in 1.9.1 raises exception for some invalid dates instead of returning false

Added by colinb2 (Colin Bartlett) over 13 years ago. Updated about 13 years ago.

Status:
Closed
Target version:
-
ruby -v:
1.9.1
Backport:
[ruby-core:32096]

Description

=begin
possible_bug = <<_possible_bug
Date._valid_civil? in 1.9.1 raises exception for some invalid dates
instead of returning false.

This is a possible bug in 1.9.1 Date._valid_civil? found while
I was testing changes to some methods in Date to make them faster.
I tried a search but couldn't find a bug report for this.

If it is a bug, then there are implications for other methods
in 1.9.1 Date, and I would be more than happy to elaborate.

For versions of Date.valid_civil? before Ruby 1.9.1, if the date
is valid then the return value is the julian day number, else nil.

In 1.9.1 Date my understanding is that the intended behaviour is
if the date is valid then the return value is true, else false.
But in the 1.9.1 version on my computer, for example:
month = -14, day = -1 returns false;
month = -13, day = -1 raises a NoMethodError exception.
The behaviour is the same on http://tryruby.org:
RUBY_VERSION #=> "1.9.1"
Date.valid_civil? 2010, -14, -1 #=> false
Date.valid_civil? 2010, -13, -1 #=>
#=> NoMethodError: undefined method `+' for nil:NilClass

The problem seems to be in the private method Date._valid_civil?
which as currently written seems not to cater for the possibility
that Date.find_ldom might return nil.
The following code shows the behaviour on my computer:
(a) using the current 1.9.1 Date._valid_civil?;
(b) after a one line patch to Date._valid_civil?
_possible_bug

puts
puts "Ruby #{RUBY_VERSION}"
puts "defined?( Date.find_ldom() )"
p defined?( Date.find_ldom() )

puts possible_bug

require "date"

def test_date_valid_civil()
y = 2010
sg = Date::ITALY
mm = [ -12, -14, -25, -13, -26, 0 ]
dd = [ -1 ]
mm.each do |m|
dd.each do |d|
print "* y=#{y}, m=#{m}, d=#{d}; sg=#{sg.inspect};"
begin
rr = Date.valid_civil?( y, m, d, sg )
puts " #=> #{rr.inspect}"
rescue
puts " #=> " + $!.inspect
end
end
end
end

puts
puts "(a) use Ruby 1.9.1 to test current 1.9.1 Date._valid_civil?"
test_date_valid_civil()

puts; puts "(b) patch and test patched Date._valid_civil?"

class Date
t = Module.new do
private

 def _valid_civil? (y, m, d, sg=GREGORIAN) # :nodoc:
   if m < 0
     m += 13
   end
   if d < 0
  #  j = find_ldom(y, m, sg)   #-
     return unless j = find_ldom(y, m, sg)  #+ patch by CWB 2010-09-06
     ny, nm, nd = jd_to_civil(j + d + 1, sg)
     return unless [ny, nm] == [y, m]
     d = nd
   end
   jd = civil_to_jd(y, m, d, sg)
   return unless [y, m, d] == jd_to_civil(jd, sg)
   jd
 end

end

extend t
include t
end

test_date_valid_civil()
=end

Actions #1

Updated by naruse (Yui NARUSE) over 13 years ago

  • Category set to lib
  • Status changed from Open to Assigned
  • Assignee set to tadf (tadayoshi funaba)
  • ruby -v set to 1.9.1

=begin

=end

Actions #2

Updated by tadf (tadayoshi funaba) over 13 years ago

  • Status changed from Assigned to Closed

=begin

=end

Actions

Also available in: Atom PDF

Like0
Like0Like0