我们必须在我们的应用程序中处理用户指定的日期格式。我们决定使用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
任何建议都将不胜感激
答案 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