Using Ruby/RoR - The year is a string in the model/view. How do I validate that the user entered string is a valid gregorian calendar year?
6 Answers
It sounds like a more direct question is: how do you validate that the user enters a string corresponding to a number between 1582 and 2500 (say). You can do this like this:
date_string.scan(/\D/).empty? and (1582..2500).include?(date_string.to_i)
that way, you can choose what a sensible year is, too - for example, is 800 really a valid answer in your application? or 3000?

- 127,331
- 53
- 180
- 211
Here's one way to do it:
Date.strptime(date_str, "%Y").gregorian?
Note that this will throw exceptions if the string is in an unexpected format. Another (more forgiving) option, is:
Date.new(date_str.to_i).gregorian?

- 15,182
- 3
- 44
- 45
At the cost of a tiny bit of cleverness/regexp magic, something like the following will allow you to test not only for whether a string is numeric (the first criteria for being a valid year) but for whether it falls within a particular range of years:
def is_valid_year?(date_str, start=1900, end=2099)
date_str.grep(/^(\d)+$/) {|date_str| (start..end).include?(date_str.to_i) }.first
end
The above function returns nil
for any string with non-numeric characters, false
for those which are numeric but outside the provided range, and true
for valid year strings.

- 12,229
- 2
- 23
- 19
-
+1-Wow nice work ... i think i should also look deep into Regex! – RubyDubee Sep 15 '09 at 15:38
-
A few (pedantic?) notes: You can't name a method parameter end (as that's a reserved keyword), and this method will return false for the string " 1999", so you may want to call .strip before .grep. – Greg Campbell Sep 15 '09 at 16:48
-
@Greg: good point on the parameter name -- I obviously extracted this from an IRb session, not a full source file, so names were changed in the browser window. Calling `#strip` might be a useful relaxation of the validation rule, but it would depend on the application. – rcoder Sep 15 '09 at 18:15
The accepted answer by @rcoder will not be working as i tested on rails 4+ . i made another simple one.
def is_valid_year? year
return false if year.to_i.to_s != year
year.strip.to_i.between?(1800, 2999)
end
The first line to not accept characters, you can also change the range between as you wish

- 175
- 11
Date.parse(string_of_date).gregorian?
Also, have a look at the documentation for the Date class.

- 25,434
- 5
- 54
- 58
-
Thanks, your suggestion doesn't work if the input is 1999 or 2005! Date.parse. is looking for YYYYMMDD, I think. – railsuser Sep 14 '09 at 21:11
-
Ah. I hadn't realized you only wanted the year (even though it says so right in the question!). My apologies. – theIV Sep 14 '09 at 21:59
Wanting to parse an integer from a string is a pretty common question for Ruby. Probably because there's no perfect approach. Maybe it deserves its own tag!
Test if a string is basically an integer in quotes using Ruby?
How do I get the second integer in a Ruby string with to_i?
Extract and multiple integers from user-input string in Ruby?
How can I convert an entire line of input into an integer in Ruby?
How do I parse a number from a String that may have a leading zero?
Retrieve number from the string pattern using regular expression

- 1
- 1

- 78,473
- 57
- 200
- 338