问题描述
我在美国,我们通常将日期格式设置为月/日/年。我试图确保我的Rails应用程序,使用Ruby 1.9,在所有地方都采用这种格式,并且在Ruby 1.8下工作。
I'm in the U.S., and we usually format dates as "month/day/year". I'm trying to make sure that my Rails app, using Ruby 1.9, assumes this format everywhere, and works the way it did under Ruby 1.8.
我知道很多的人有这个问题,所以我想在这里创建一个明确的指南。
I know that lots of people have this issue, so I'd like to create a definitive guide here.
具体来说:
- '04 / 01/2011'是2011年4月1日,而不是2011年1月4日。
- '4/1/2011'也是2011年4月1日 - 不需要前导零。
我该怎么做?
这是我到目前为止。
我在 application.rb
中有这一行:
# Format our dates like "12/25/2011'
Date::DATE_FORMATS[:default] = '%m/%d/%Y'
确保如果我执行以下操作:
This ensures that if I do the following:
d = Date.new(2011,4,1)
d.to_s
...我得到04 / 01/20 11,而不是2011-04-01。
... I get "04/01/2011", not "2011-04-01".
ActiveSupport的 String#to_date
方法目前看起来像这样():
ActiveSupport's String#to_date
method currently looks like this (source):
def to_date
return nil if self.blank?
::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday))
end
(如果你不遵循这一点,第二行创建一个新的日期,以年,月,日顺序。它通过使用 Date._parse
获得年,月和日值,它解析一个字符串,并以某种方式决定这些值是什么,然后返回一个哈希值。 .values_at
按照 Date.new
要求他们的顺序拉出该哈希值。)
(In case you don't follow that, the second line creates a new date, passing in year, month and day, in that order. The way it gets the year, month and day values is by using Date._parse
, which parses a string and somehow decides what those values are, then returns a hash. .values_at
pulls the values out of that hash in the order Date.new
wants them.)
由于我知道我通常会传递像04/01/2011或4/1/2011这样的字符串,我可以通过monkeypatching来修复它:
Since I know that I will normally pass in strings like "04/01/2011" or "4/1/2011", I can fix this by monkeypatching it like this:
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;
此解决方案使我的测试通过,但它是疯狂的吗?我只是在某个地方缺少一个配置选项,还是有其他更容易的解决方案?
This solution makes my tests pass, but is it crazy? Am I just missing a configuration option somewhere, or is there some other, easier solution?
有没有其他的日期解析案例我没有覆盖? >
Are there any other date-parsing cases I'm not covering?
推荐答案
宝石:ruby-american_date
题。我现在正在使用它,并且很高兴。
Gem: ruby-american_date
This gem was created since I asked this question. I'm now using it and have been pleased.
这篇关于如何使用Ruby 1.9在Rails中使用美式日期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!