Home > Enterprise >  Date validation in ruby not working for the 'year'
Date validation in ruby not working for the 'year'

Time:12-13

I have the below code to verify the dates are in correct format and in range. I cna't figure out why year is not validated properly.

def valid_date?(date)
  DateTime.strptime(date, '%Y-%m-%d %H:%M:%S')
  true
rescue ArgumentError
  false
end

puts valid_date?("202-02-20 00:00:00").inspect # ❌ returns true. But this is wrong. Year shouldn't be 202.
puts valid_date?("2020/02/20 00:59:00").inspect # ✅ false. This is correct behavior. 
puts valid_date?("2020-02-31 00:00:00").inspect # ✅ returns false. This is correct behavior. Date for Feb cannot be 31.
puts valid_date?("2020-02-20 24:00:00").inspect # ✅ true. This is correct behavior. 
puts valid_date?("2020-02-20 00:00:00").inspect # ✅ true. This is correct behavior.
puts valid_date?("2020-02-20 25:00:00").inspect # ✅ false. This is correct behavior.
puts valid_date?("2020-02-20 00:59:00").inspect # ✅ true. This is correct behavior.

CodePudding user response:

I think you need to use a different approach to validating dates for your purposes. The fact is that strptime will recognize any value >=0 as a valid year and similarly will recognize other values (month, day, hours, minutes, and seconds) without requiring the specific number of digits. Consider the following example:

DateTime.strptime("0-1-1 0:0:0", '%Y-%m-%d %H:%M:%S')
#=>  0000-01-01T00:00:00 00:00

...and when applied to your code:

valid_date?("0-1-1 0:0:0")
#=>  true

CodePudding user response:

%Y is simply "year with century" and can even be negative. The "4 digits at least" does not seem to be true for parsing, only formatting.

%Y - Year with century (can be negative, 4 digits at least)
     -0001, 0000, 1995, 2009, 14292, etc.
# 0002-02-20T00:59:00 00:00
puts DateTime.strptime("2-02-20 00:59:00", '%Y-%m-%d %H:%M:%S')

You'll need to add any arbitrary extra constraints on the date. For example, if you only want year 2000 or sooner...

require 'date'

def valid_date?(input)
  date = DateTime.strptime(input, '%Y-%m-%d %H:%M:%S')
  date.year >= 2000
rescue ArgumentError
  false
end
  • Related