开发者

How to get strptime to raise ArgumentError with garbage trailing characters

We have to handle user specified date formats in our application. We decided to go with Date.strptime for parsing and validation, which works great, except for how it just ignores any garbage data entered. Here is an irb session demonstrating the issue

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" 

wha开发者_如何学编程t we would like, is behavior more like this

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

Any suggestions would be appreciated


One possibility is to pass the resulting date through strftime using the same format and compare to the original string.

i.e. valid = Date.strptime(date_string, format).strftime(format) == date_string

One limitation of this is that it wouldn't handle leading 0s in parts of the date e.g. if you wanted to accept 2010-6-1 but strftime returned 2010-06-01 you wouldn't have a match.

Also, I'm not sure if this is what you meant or not, but your second example Date.strptime '2001failfailfail-01-01', '%Y-%m-%d' does raise an ArgumentError. It seems like only trailing junk is ignored.


one way is to define a new class which does the validation first.

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

Another way would be to open up the Date class, alias the strptime method, write a new one to do the validation you require and then call the aliased one.

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   
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜