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