Formatting Dates, Times, and Currencies

Problem

Contributed by: Andy Shen

You want to know how to format dates, times, and currencies in your application's views.

Solution

Rails provides the following two default formats for formatting date or time objects:

>> Date.today.to_formatted_s(:short)
=> "1 Oct"
>> Date.today.to_formatted_s(:long)
=> "October 1, 2006"

If you need a different format, use strftime with a format string:

>> Date.today.strftime("Printed on %d/%m/%Y")
=> "Printed on 01/10/2006"

See for a complete list of formatting options.

Table 5-1. Date format string options
Symbol Meaning
%a The abbreviated weekday name ("Sun")
%A The full weekday name ("Sunday")
%b The abbreviated month name ("Jan")
%B The full month name ("January")
%c The preferred local date and time representation
%d Day of the month (01..31)
%H Hour of the day, 24-hour clock (00..23)
%I Hour of the day, 12-hour clock (01..12)
%j Day of the year (001..366)
%m Month of the year (01..12)
%M Minute of the hour (00..59)
%p Meridian indicator ("AM" or "PM")
%S Second of the minute (00..60)
%U Week number of the current year (00..53)
%W Week number of the current year (00..53)
%w Day of the week (Sunday is 0, 0..6)
%x Preferred representation for the date alone, no time
%X Preferred representation for the time alone, no date
%y Year without a century (00..99)
%Y Year with century
%Z Time zone name
%% Literal % character

There are some other options not documented in the API. You can use many of the date and time formatting options listed in the Unix manpages or C documentation in Ruby. For example:

  • %e is replaced by the day of month as a decimal number (131); single digits are preceded by a space
  • %R is equivalent to %H:%M
  • %r is equivalent to %I:%M:%S %p
  • %v is equivalent to %e-%b-%Y

Here's the current date:

>> Time.now.strftime("%v")
=> " 2-Oct-2006"

All of the format options apply to Time objects, but not all the options makes sense when used on Date objects. Here's one to format a Date object:

>> Date.today.strftime("%Y-%m-%d %H:%M:%S %p")
=> "2006-10-01 00:00:00 AM"

The same option invoked on a Time object would result in:

>> Time.now.strftime("%Y-%m-%d %H:%M:%S %p")
=> "2006-10-01 23:49:38 PM"

There doesn't seems to be a format string for a single digit month, so it'll have to do something different, for example:

"#{date.day}/#{date.month}/#{date.year}"

For currency, Rails provides a number_to_currency method. The most basic use for this method is passing in a number you want to display as currency:

>> number_to_currency(123.123)
=> "$123.12"

The method can have a hash as its second parameter. The hash can specify the following four options

  • Precision (default = 2)
  • Unit (default = "$")
  • Separator (default = ".")
  • Delimiter (default = ",")
>> number_to_currency(123456.123, {"precision" => 1, :unit => "#", 
 :separator => "-", :delimiter => "^"})
=> "#123^456-1"

Discussion

It's a good idea to consolidate any formatting code you need in a Rails helper class, such as ApplicationHelper, so all your views can benefit from it:

app/helpers/application_helper.rb:

module ApplicationHelper
 def render_year_and_month(date)
 h(date.strftime("%Y %B"))
 end
 def render_date(date)
 h(date.strftime("%Y-%m-%d"))
 end
 def render_datetime(time)
 h(time.strftime("%Y-%m-%d %H:%M"))
 end end

See Also