Exibir intervalos de datas em texto no Rails

Edit: Este ajudante agora vem na forma da gema time_will_tell !

Sempre quis exibir intervalos de datas que seguem este formato:

3 – 8 de outubro de 2012

30 de janeiro – 5 de fevereiro de 2013

26 de dezembro de 2012 – 3 de janeiro de 2013

Observe que os meses e anos só aparecem quando apropriado. Você quer isso? Basta adicionar este time_helper.rbajudante em seus ajudantes:

# encoding: utf-8
module TimeHelper

def date_range(from_date, until_date, options = {})
options
.symbolize_keys!
format
= options[:format] || :short
separator
= options[:separator] || "—"

if format.to_sym == :short
month_names
= I18n.t("date.abbr_month_names")
else
month_names
= I18n.t("date.month_names")
end

from_day
= from_date.day
from_month
= month_names[from_date.month]
from_year
= from_date.year
until_day
= until_date.day

dates
= { from_day: from_day }

if from_date.month == until_date.month && from_date.year == until_date.year
date_format
= "same_month"
dates
.merge!(until_day: until_day, month: from_month, year: from_year)
else
until_month
= month_names[until_date.month]

dates
.merge!(from_month: from_month, until_month: until_month, until_day: until_day)

if from_date.year == until_date.year
date_format
= "different_months_same_year"
dates
.merge!(year: from_year)
else
until_year
= until_date.year

date_format
= "different_years"
dates
.merge!(from_year: from_year, until_year: until_year)
end
end

I18n
.t("date_range.#{format}.#{date_format}", dates.merge(sep: separator))
end

end

E o seguinte em qualquer lugar em suas localidades (eu uso active_support.en.yml:

en:
date_range
:
long:
different_months_same_year
: "%{from_month} %{from_day} %{sep} %{until_month} %{until_day}, %{year}"
different_years
: "%{from_month} %{from_day}, %{from_year} %{sep} %{until_month} %{until_day}, %{until_year}"
same_month
: "%{month} %{from_day} %{sep} %{until_day}, %{year}"
short:
different_months_same_year
: "%{from_month} %{from_day} %{sep} %{until_month} %{until_day}, %{year}"
different_years
: "%{from_month} %{from_day}, %{from_year} %{sep} %{until_month} %{until_day}, %{until_year}"
same_month
: "%{month} %{from_day} %{sep} %{until_day}, %{year}"

Então, sempre que quiser exibir um intervalo de datas, basta usar o seguinte:

<%= date_range(from_date, until_date) %>

Observe que existem 2 opções no código acima:

formatque pode ser ou (para nomes curtos de meses ou nomes completos) para especificar o separador a ser usado entre as datas:short:long

separator