Module: Incline::Extensions::DateValue

Defined in:
lib/incline/extensions/date_value.rb

Overview

Patches the ActiveRecord Date value to accept more date formats.

Specifically this will allow ActiveRecord models to receive dates in US format or ISO format.

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object

Patches the ActiveRecord Date value type.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/incline/extensions/date_value.rb', line 15

def self.included(base)
  base.class_eval do

    private

    undef cast_value

    def cast_value(string)
      return nil if string.blank?
      return string if string.is_a?(::Time)

      if string.is_a?(::String)

        begin
          # if it matches either of our formats, we can try using it.
          if (match = (Incline::DateTimeFormats::US_DATE_FORMAT.match(string) || Incline::DateTimeFormats::ALMOST_ISO_DATE_FORMAT.match(string)))

            year = match['YEAR'].to_s.to_i
            year += 2000 if year < 50
            year += 1900 if year < 100
            month = match['MONTH'].to_s.to_i
            mday = match['DAY'].to_s.to_i

            # ensure the date portion is valid.
            dt =
                begin
                  Time.utc(year, month, mday)
                rescue
                  raise "Invalid date (#{$!.message})."
                end

            raise 'Invalid date (day of month is invalid for month).' unless dt.year == year && dt.month == month && dt.mday == mday

            ::Date.new(year, month, mday)
          else
            # use the fallback if it doesn't match our formats.
            fallback_string_to_date(string)
          end
        rescue
          Incline::Log::warn "Failed to parse #{string.inspect}: #{$!.message}"
          nil
        end

      elsif string.respond_to?(:to_date)
        begin
          string.to_date
        rescue
          Incline::Log::warn "Failed to convert #{string.inspect} to date: #{$!.message}"
          nil
        end
      else
        nil
      end
    end
  end
end