How to check if a string is a valid date

后端 未结 15 1316
礼貌的吻别
礼貌的吻别 2020-12-02 08:09

I have a string: \"31-02-2010\" and want to check whether or not it is a valid date. What is the best way to do it?

I need a method which which returns

相关标签:
15条回答
  • 2020-12-02 08:35

    Parsing dates can run into some gotcha's, especially when they are in a MM/DD/YYYY or DD/MM/YYYY format, such as short dates used in U.S. or Europe.

    Date#parse attempts to figure out which to use, but there are many days in a month throughout the year when ambiguity between the formats can cause parsing problems.

    I'd recommend finding out what the LOCALE of the user is, then, based on that, you'll know how to parse intelligently using Date.strptime. The best way to find where a user is located is to ask them during sign-up, and then provide a setting in their preferences to change it. Assuming you can dig it out by some clever heuristic and not bother the user for that information, is prone to failure so just ask.

    This is a test using Date.parse. I'm in the U.S.:

    >> Date.parse('01/31/2001')
    ArgumentError: invalid date
    
    >> Date.parse('31/01/2001') #=> #<Date: 2001-01-31 (4903881/2,0,2299161)>
    

    The first was the correct format for the U.S.: mm/dd/yyyy, but Date didn't like it. The second was correct for Europe, but if your customers are predominately U.S.-based, you'll get a lot of badly parsed dates.

    Ruby's Date.strptime is used like:

    >> Date.strptime('12/31/2001', '%m/%d/%Y') #=> #<Date: 2001-12-31 (4904549/2,0,2299161)>
    
    0 讨论(0)
  • 2020-12-02 08:36

    Method:

    require 'date'
    def is_date_valid?(d)
      Date.valid_date? *"#{Date.strptime(d,"%m/%d/%Y")}".split('-').map(&:to_i) rescue nil
    end
    

    Usage:

    config[:dates].split(",").all? { |x| is_date_valid?(x)}
    

    This returns true or false if config[:dates] = "12/10/2012,05/09/1520"

    0 讨论(0)
  • 2020-12-02 08:37

    Try regex for all dates:

    /(\d{1,2}[-\/]\d{1,2}[-\/]\d{4})|(\d{4}[-\/]\d{1,2}[-\/]\d{1,2})/.match("31-02-2010")
    

    For only your format with leading zeroes, year last and dashes:

    /(\d{2}-\d{2}-\d{4})/.match("31-02-2010")
    

    the [-/] means either - or /, the forward slash must be escaped. You can test this on http://gskinner.com/RegExr/

    add the following lines, they will all be highlighted if you use the first regex, without the first and last / (they are for use in ruby code).

    2004-02-01
    2004/02/01
    01-02-2004
    1-2-2004
    2004-2-1
    
    0 讨论(0)
  • 2020-12-02 08:43

    A stricter solution

    It's easier to verify the correctness of a date if you specify the date format you expect. However, even then, Ruby is a bit too tolerant for my use case:

    Date.parse("Tue, 2017-01-17", "%a, %Y-%m-%d") # works
    Date.parse("Wed, 2017-01-17", "%a, %Y-%m-%d") # works - !?
    

    Clearly, at least one of these strings specifies the wrong weekday, but Ruby happily ignores that.

    Here's a method that doesn't; it validates that date.strftime(format) converts back to the same input string that it parsed with Date.strptime according to format.

    module StrictDateParsing
      # If given "Tue, 2017-01-17" and "%a, %Y-%m-%d", will return the parsed date.
      # If given "Wed, 2017-01-17" and "%a, %Y-%m-%d", will error because that's not
      # a Wednesday.
      def self.parse(input_string, format)
        date = Date.strptime(input_string, format)
        confirmation = date.strftime(format)
        if confirmation == input_string
          date
        else
          fail InvalidDate.new(
            "'#{input_string}' parsed as '#{format}' is inconsistent (eg, weekday doesn't match date)"
          )
        end
      end
    
      InvalidDate = Class.new(RuntimeError)
    end
    
    0 讨论(0)
  • 2020-12-02 08:44

    You can try the following, which is the simple way:

    "31-02-2010".try(:to_date)
    

    But you need to handle the exception.

    0 讨论(0)
  • 2020-12-02 08:45
    d, m, y = date_string.split '-'
    Date.valid_date? y.to_i, m.to_i, d.to_i
    
    0 讨论(0)
提交回复
热议问题