Date And Time Formats With Rails

  Ruby   Rails  
 Nov 2019

dates

Rails comes with some default date and time formats. There are good docs for them here:

Rails Date Class

Rails DateTime Class

Unfortunately, I don’t like the default formats! Or maybe they just look odd because I’m British. Or maybe your client insists on something odd. Whatever, you can set up your own. Here are my favourites.

# config/initializers/time_Formats.rb
Date::DATE_FORMATS[:short] = ->(date) { date.strftime("#{date.day.ordinalize} %b %Y") }
Date::DATE_FORMATS[:long] = ->(date) { date.strftime("#{date.day.ordinalize} %B %Y") }
Date::DATE_FORMATS[:longer] = ->(date) { date.strftime("%a #{date.day.ordinalize} %B %Y") }
Date::DATE_FORMATS[:full] = ->(date) { date.strftime("%A #{date.day.ordinalize} %B %Y") }

Time::DATE_FORMATS[:short] = ->(date) { date.strftime("%H:%M #{date.day.ordinalize} %b %Y") }
Time::DATE_FORMATS[:long] = ->(date) { date.strftime("%H:%M #{date.day.ordinalize} %B %Y") }
Time::DATE_FORMATS[:longer] = ->(date) { date.strftime("%H:%M %a #{date.day.ordinalize} %B %Y") }
Time::DATE_FORMATS[:full] = ->(date) { date.strftime("%H:%M %A #{date.day.ordinalize} %B %Y") }

Time::DATE_FORMATS[:short_civillian] = ->(date) { date.strftime("%l:%M%P #{date.day.ordinalize} %b %Y") }
Time::DATE_FORMATS[:long_civillian] = ->(date) { date.strftime("%l:%M%P #{date.day.ordinalize} %B %Y") }
Time::DATE_FORMATS[:longer_civillian] = ->(date) { date.strftime("%l:%M%P %a #{date.day.ordinalize} %B %Y") }
Time::DATE_FORMATS[:full_civillian] = ->(date) { date.strftime("%l:%M%P %A #{date.day.ordinalize} %B %Y") }


And now your use them in your templates.

<%= Date.today.to_s(:short) %>
23rd Nov 2019
23rd November 2019
Sat 23rd November 2019
Saturday 23rd November 2019
14:57 1st Nov 2019
14:57 1st November 2019
14:57 Fri 1st November 2019
14:57 Friday 1st November 2019
2:57pm 1st Nov 2019
2:57pm 1st November 2019
2:57pm Fri 1st November 2019
2:57pm Friday 1st November 2019

You can also add your formats to locales, allowing you to have different formats per country or region. For example, UK and USA formats.

Usually, you would add your translations to a yml file. You can still do that, but add your date formats to a rb file, so you can use ruby to ordinalize your dates.

#config/locales/en.yml
en:
  hello: "Hello world"  

config/locales/en.rb
{
  :en => {
    :date => {
      :formats => {
        :short => lambda { |date, _| "%b, #{date.day.ordinalize}   %Y" }
      }
    }
  }
}

You have to actually tell Rails about a locale, not just add the yml.

/config/initializers/locale.rb
I18n.available_locales = [:en, "en-US"]

You will also want to set a default locale for en-US to inherit from so that things like date.abbr_month_names are available.

# rails will fallback to config.i18n.default_locale translation
config.i18n.fallbacks = true

# rails will fallback to en, no matter what is set as config.i18n.default_locale
config.i18n.fallbacks = [:en]

# fallbacks value can also be a hash - a map of fallbacks if you will
# missing translations of es and fr languages will fallback to english
# missing translations in german will fallback to french ('de' => 'fr')
config.i18n.fallbacks = {'es' => 'en', 'fr' => 'en', 'de' => 'fr'}

Now you can add your locale:

{
  "en-US" => {
    :date => {
      :formats => {
        :short => lambda { |date, _| "#{date.day.ordinalize}  %b %Y" }
      }
    }
  }
}

And now, you can say your dates all backwards like a boss : )

  <%= l(Date.today, :format => :short, locale: :'en') %>
  1st Nov 2019
  <%= l(Date.today, :format => :short, locale: :'en-US') %>
  Nov, 1st 2019

Check out the I18n Docs on the rails guides or just crib from above and get going with your date formats.


Web Development

Got a web project you need doing well? We can help with that!

Find out more