代码之家  ›  专栏  ›  技术社区  ›  Matt Briggs

如何让strptime用垃圾尾随字符引发argumenterror

  •  2
  • Matt Briggs  · 技术社区  · 14 年前

    我们必须在应用程序中处理用户指定的日期格式。我们决定一起去 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 回复  |  直到 14 年前
        1
  •  1
  •   mikej heading_to_tahiti    14 年前

    一种可能是通过 strftime 使用相同的格式并与原始字符串进行比较。

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

    其中一个限制是,它不会处理日期的某些部分的前导0,例如,如果您想接受2010-6-1,但是 斯特夫时间 返回2010-06-01你将没有比赛。

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

        2
  •  0
  •   stephenr    14 年前

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

    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
    

    另一种方法是打开日期类,为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