7.10. Validating a Date/TimeAs we saw in section 7.5 "Finding the Nth Weekday in a Month," the standard date/time functions do not check the validity of a date, but "roll it over" as needed. For example, November 31 is translated to December 1. At times, this may be the behavior you want. If it is not, you will be happy to know that the standard library Date does not regard such a date as valid. We can use this fact to perform validation of a date as we instantiate it. class Time def Time.validate(year, month=1, day=1, hour=0, min=0, sec=0, usec=0) require "date" begin d = Date.new(year,month,day) rescue return nil end Time.local(year,month,day,hour,min,sec,usec) end end t1 = Time.validate(2000,11,30) # Instantiates a valid object t2 = Time.validate(2000,11,31) # Returns nil Here we have taken the lazy way out; we simply set the return value to nil if the parameters passed in do not form a valid date (as determined by the Date class). We have made this method a class method of Time by analogy with the other methods that instantiate objects. Note that the Date class can work with dates prior to the epoch. This means that passing in a date such as 31 May 1961 will succeed as far as the Date class is concerned. But when these values are passed into the Time class, an ArgumentError will result. We don't attempt to catch that exception here because we think it's appropriate to let it be caught at the same level as (for example) Time.local, in the user code. Speaking of Time.local, we used that method here; but if we wanted GMT instead, we could have called the gmt method. It would be a good idea to implement both flavors. |