如何使用Ruby 1.9在Rails中使用美式日期?

Nat*_*ong 12 ruby ruby-on-rails date ruby-1.9

我在美国,我们通常将日期格式设置为"月/日/年".我正在努力确保使用Ruby 1.9的Rails应用程序在任何地方都采用这种格式,并按照它在Ruby 1.8下的方式工作.

我知道很多人都有这个问题,所以我想在这里创建一个明确的指南.

特别:

  1. '04/01/2011'是2011年4月1日,而不是2011年1月4日.
  2. '2011年4月1日'也是2011年4月1日 - 不需要领先的零.

我怎样才能做到这一点?

这是我到目前为止所拥有的.

控制日期#to_s行为

我有这条线application.rb:

    # Format our dates like "12/25/2011'
    Date::DATE_FORMATS[:default] = '%m/%d/%Y'
Run Code Online (Sandbox Code Playgroud)

这确保了如果我执行以下操作:

d = Date.new(2011,4,1)
d.to_s
Run Code Online (Sandbox Code Playgroud)

......我得到"04/01/2011",而不是"2011-04-01".

控制String#to_date行为

ActiveSupport的String#to_date方法目前看起来像这样(来源):

 def to_date
    return nil if self.blank?
    ::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday))
  end
Run Code Online (Sandbox Code Playgroud)

(如果你不遵循这个,第二行创建一个新的日期,按年顺序传递年,月和日.它获取年,月和日值的方式是使用Date._parse,它解析字符串和以某种方式决定这些值是什么,然后返回一个哈希值..values_at按顺序从该哈希值中拉出值Date.new.)

因为我知道我通常会传递像"04/01/2011"或"4/1/2011"这样的字符串,所以我可以通过monkeypatching来解决这个问题:

class String

  # Keep a pointer to ActiveSupport's String#to_date
  alias_method :old_to_date, :to_date

  # Redefine it as follows
  def to_date
    return nil if self.blank?
    begin
      # Start by assuming the values are in this order, separated by /
      month, day, year = self.split('/').map(&:to_i)
      ::Date.new(year, month, day)
    rescue
      # If this fails - like for "April 4, 2011" - fall back to original behavior
      begin
      old_to_date
      rescue NoMethodError => e
        # Stupid, unhelpful error from the bowels of Ruby date-parsing code
        if e.message == "undefined method `<' for nil:NilClass"
          raise InvalidDateError.new("#{self} is not a valid date")
        else
          raise e
        end
      end
    end
  end
end

class InvalidDateError < StandardError; end;
Run Code Online (Sandbox Code Playgroud)

这个解决方案使我的测试通过,但它是疯了吗?我在某处错过了配置选项,还是有其他更简单的解决方案?

我还没有覆盖其他日期解析案例吗?

Nat*_*ong 9

宝石:ruby-american_date

这个宝石是在我问这个问题后创建的.我现在正在使用它并且很高兴.

https://github.com/jeremyevans/ruby-american_date