3

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?

madcolor
  • 8,105
  • 11
  • 51
  • 74
railsuser
  • 53
  • 5

6 Answers6

5

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?

Peter
  • 127,331
  • 53
  • 180
  • 211
5

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?
Greg Campbell
  • 15,182
  • 3
  • 44
  • 45
3

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.

rcoder
  • 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
3

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

0
Date.parse(string_of_date).gregorian?

Also, have a look at the documentation for the Date class.

theIV
  • 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