Customizing datetime format in en.yml in Rails 3

后端 未结 4 1769
北海茫月
北海茫月 2021-02-01 18:15

According to documentation at http://guides.rubyonrails.org/i18n.html#adding-date-time-formats, the best way to ask for specific formats for a date is to define them in /config/

相关标签:
4条回答
  • 2021-02-01 18:52

    [several years later...]

    If you want to DRY up your date formats and/or you have legacy code with to_s all over the place and don't plan to internationalize your app, you can do this:

    I18n.t('date.formats').each do |key, value|
      Date::DATE_FORMATS[key] = value
    end
    

    Then just define your formats in config/locales/en.yml. Of course if you ever plan to translate your app, you'll need to change all occurrences of to_s to use the I18n.l method suggested below.

    You can also use this without Rails. Just add the following before the above code:

    require 'active_support/time'
    I18n.load_path << 'en.yml'
    
    0 讨论(0)
  • 2021-02-01 19:03

    [Several months later...]

    The problem is that you're trying to define a "datetime" format in en.yml, but the Rails localization code only checks for "date" or "time" (lumping "datetime" in with "time").

    The offending code is in the i18n base code here, on line 53:

    type = object.respond_to?(:sec) ? 'time' : 'date'

    It checks if the given object can respond to "sec"; if so, it reads the "time" stuff in en.yml, if not, it reads the "date" format. No "datetime".

    As Tyrael suggested, you can force it to obey your will at gunpoint via the initialization code. That will certainly work, but now you've put localization code into your initializers. That's potentially confusing and messy, IMO.

    IMO, a cleaner way to do this would be to add the format you want for DateTime to the 'time' section of en.yml by specifying a different 'format', like so:

    en:
      time:
        formats:
          short_datetime: %B %d, %Y
          long_datetime:  %B %d, %Y, at %r
          hammer_datetime: STOP! %B %d, %Y, is HAMMERTIME!
          # and so on... da dum... da dum...
    

    Which you could use like this:

    <%= l item.create_date, :format => :short_datetime %>
    

    That's the approach I use meself.

    But for completeness, you could also do this:

    en:
      datetime:
        formats:
          default: %B %d, %Y
    

    And then tell Rails how to read it, like this:

    # In your Application Helper
    def localize_datetime(dt)
      # quick-and-dirty demo... doesn't accept different format options and stuff...
      dt.strftime(I18n.t(:"datetime.formats.default", {:locale => I18n.locale }))
    end
    def ld(dt)
      localize_datetime(dt)
    end
    # or something like that...
    

    Then use it like so:

    <%= ld item.create_date %>
    

    This would keep your localization info in your localization files, but it requires getting your hands dirty (code above doesn't do any error checking, doesn't accept parameters, etc.), and forces you to use a different function for outputting it (instead of just "l", a painfully long "ld").

    Lastly (and probably leastly), we could just tell the Rails gnomes to fix that function so it allows "datetime". :)

    Hope that was useful. Best of luck.

    0 讨论(0)
  • 2021-02-01 19:08

    just want to clarify that if you use with active record, just simply convert the string datetime value to date object as example below.

    en:
      date:
        formats:
          default: "%Y-%m-%d"
          short: "%b %d"
          long: "%B %d, %Y"
    

    <%= l(post.the_created_at.to_date, format: :long) %>

    0 讨论(0)
  • 2021-02-01 19:10

    I suspect the problem here is in Rails' I18n:l function. Try with this:

    1. Add below lines to one of your initializer files, e.g., config/environment.rb:

      DateTime::DATE_FORMATS[:short]="short %Y-%m-%d %H:%M:%S"

      Time::DATE_FORMATS[:short] = "short %Y-%m-%d %H:%M:%S"

      Date::DATE_FORMATS[:short] = "short %Y-%m-%d"

    2. modify view:

      <%= item.create_date.to_s(:short) %>

    You can see output change to "short something".

    I know it's not a perfect answer, but hope it can give you some hints(I didn't have time to check the I18n::l function).

    0 讨论(0)
提交回复
热议问题