[Rails] [SOLVED] time validation (the feb. 31st problem)

Ara T Howard Ara.T.Howard at noaa.gov
Sun Mar 13 23:53:37 GMT 2005


the essence of this solution is as follows: Time::mktime, Time::local
and friends all have the possibility of 'normalizing' their arguments. 
that is to say a time created with

  Time::local 2000, 2, 31

can be 'normalized' into

  Wed Mar 03 00:00:00 MST 1999

this is consistent with the underlying system calls.  however, it
clearly was constructed from 'bad' input since the input month is not
the same as the output one.  this is the logic behind the following
example of time validation using rails and should be complete for
Time::mktime, Time::local, Time::gm, and Time::utc



class DbTableWithTimestampField < ActiveRecord::Base
  protected
    def validate(*a, &b)
      t = timestamp_fieldname
      if t.normalized?
        values = t.original_arguments
        errors.add self.class.to_s, "bad time from <#{values.inspect}>"
      end
      super
    end
end

class ::Time
  class << self
    def normalized? t, values
      tvalues = %w(year month day hour min sec usec).map{|m| t.send m}
      values.zip(tvalues){|vin,vout| return true if vin != vout}
      return false
    end

    %w( local mktime gm utc ).each do |method|
      eval <<-code
        alias __org_#{ method }__ #{ method }
        def #{ method }(*a, &b)
          t = __org_#{ method }__(*a, &b)
          t.instance_eval{@original_arguments = a}
          t.instance_eval{@normalized = self.class.normalized? self, a}
          t
        end
      code
    end
  end

  attr_reader 'normalized'
  alias_method 'normalized?', 'normalized'
  attr_reader 'original_arguments'
end

this results in an error page which looks something like:

  1 error prohibited this timestamp_fieldname from being saved

  There were problems with the following fields:

    * DbTableWithTimestampField bad time from <[2005, 2, 31, 12, 36]>

kind regards.

ps. my email is fried and i'm posting from messenger so this email may
or may not be formatted as i'd like it be.

-a



More information about the Rails mailing list