Как я могу использовать даты в стиле США в рельсах, используя Ruby 1.9?

Я в США, и мы обычно форматируем даты как «месяц / день / год». Я пытаюсь убедиться, что мои рельсы приложение, использующие Ruby 1.9, предполагают этот формат повсюду и работает так, как он сделал под Ruby 1.8.

Я знаю, что многие люди имеют этот вопрос, поэтому я хотел бы создать окончательное руководство здесь.

В частности:

  1. '04 / 01/2011 '- 1 апреля 2011 года, а не 4 апреля 2011 года, а не 4 января 2011 года.
  2. ' 4/1/2011 'также 1 апреля 2011 года - ведущие нули не должны быть необходимый.

Как я могу сделать это?

Вот что у меня так далеко.

Управляющая дата # to_s поведение

У меня есть эта строка в Application.rb :

    # Format our dates like "12/25/2011'
    Date::DATE_FORMATS[:default] = '%m/%d/%Y'

Это гарантирует, что если я сделаю следующее:

d = Date.new(2011,4,1)
d.to_s

... я получаю »04/01 / 2011 ", а не" 2011-04-01 ".

Управляющая строка # to_date поведение

Строка ActiveSupport # to_date В настоящее время выглядит следующим образом ( источник ):

 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 хочет их.)

Так как я знаю, что я буду Обычно пропустите строки, такие как «04/01/2011» или «4/01/2011» или «4/1/2011», я могу это исправить от обезьян, подобное это:

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;

Это решение делает мои тесты, но это сумасшедший? Я просто пропускаю вариант конфигурации где-то вариант, или есть еще какое-то другое, легчее решение?

Есть ли другие другие случаи разбора свидания, я не покрываю?

12
задан Nathan Long 13 May 2012 в 00:33
поделиться