如何使用垃圾尾随字符引发strptime引发ArgumentError

时间:2010-06-03 17:10:23

标签: ruby validation parsing date

我们必须在我们的应用程序中处理用户指定的日期格式。我们决定使用Date.strptime进行解析和验证,这非常有效,除了它如何忽略输入的任何垃圾数据。这是一个展示问题的irb会议

ree-1.8.7-2010.01 > require 'date'
 => true 
ree-1.8.7-2010.01 > d = Date.strptime '2001-01-01failfailfail', '%Y-%m-%d'
 => #<Date: 4903821/2,0,2299161> 
ree-1.8.7-2010.01 > d.to_s
 => "2001-01-01" 

我们想要的是更像这样的行为

ree-1.8.7-2010.01 > d = Date.strptime '2001failfailfail-01-01', '%Y-%m-%d'
ArgumentError: invalid date

任何建议都将不胜感激

2 个答案:

答案 0 :(得分:1)

一种可能性是使用相同的格式通过strftime传递结果日期,并与原始字符串进行比较。

即。 valid = Date.strptime(date_string, format).strftime(format) == date_string

这方面的一个限制是,它不会在日期的某些部分处理前导0,例如如果您想接受2010-6-1但strftime返回2010-06-01则不会有匹配。

另外,我不确定这是不是你的意思,但你的第二个例子Date.strptime '2001failfailfail-01-01', '%Y-%m-%d'确实引发了ArgumentError。似乎只会忽略尾随垃圾。

答案 1 :(得分:0)

一种方法是定义一个先进行验证的新类。

require 'date'

class Mydate 

    def self.strptime(string)
        raise ArgumentError 'Fail' if  string !~ /^\d\d\d\d-\d\d-\d\d$/
        Date.strptime(string)
    end
end

d = Mydate.strptime '2001-01-01'
puts d

d2 = Mydate.strptime '2001-01-02xxxx'
puts d2

另一种方法是打开Date类,为strptime方法添加别名,编写一个新的来进行所需的验证,然后调用别名。

require 'date'

class Date

    class << self
        alias :orig_strptime :strptime
    end

    def self.strptime(string)
        puts "in new strptime"
        raise ArgumentError 'Fail' if  string !~ /^\d\d\d\d-\d\d-\d\d$/ 
        Date.orig_strptime(string) 
    end  
end

d = Date.strptime '2001-01-01'
puts d

d2 = Date.strptime '2001-01-02xxxx'
puts d2