Skip to main content Link Search Menu Expand Document (external link)

Time Format

In the posts index page, if you take a look at the data displayed in created_at column, you will see that the dates are formatted like this: 2023-03-25 13:24:12 +0800. The format is too long and it includes the time zone which is redundant in most cases. It also follows a pattern that may not meet the specifications that you want.

Ruby has built in methods that will help you handle this problem, these methods allows you to convert the time into a string that follows a specific pattern.

Table of Contents

  1. Formatting Time Using strftime
  2. Formatting Time Using to_fs

Formatting Time Using strftime

strftime formats date according to the directives in the given format string. The directives begin with a percent (%) character. Any text not listed as a directive will be passed through to the output string.

Let’s try to use this to format the created_at in the posts index page.

<!-- app/views/posts/index.html.erb -->
  
<!-- ... -->
<table>
  <!-- ... -->
  </thead>
  <% @posts.each do |post| %>
    <tr>
      <!-- ... -->
-     <td><%= post.created_at %></td>
+     <td><%= post.created_at.strftime("%Y/%m/%d %I:%M %p") %></td>
      <!-- ... -->
    </tr>
  <% end %>
</table>
<!-- ... -->

The time format of created_at changed from the default "%Y-%m-%d %H:%M:%S %z" to "%Y/%m/%d %I:%M %p". The seconds and the time zone are removed, and it is converted to 12-hour clock format.

Below are the most commonly used directive, refer to Ruby Date Format (strftime) Cheat Sheet for the full list:

Date formatting

%YYear with century (e.g. 2015, 1995, etc)
%mMonth of the year, zero-padded (01..12)
%BThe full month name (e.g. January)
%bThe abbreviated month name (e.g. Jan)
%dDay of the month, zero-padded (01..31)
%jDay of the year (001..366)

Time Formatting

%HHour of the day, 24-hour clock, zero-padded (00..23)
%kHour of the day, 24-hour clock, blank-padded (_0..23)
%IHour of the day, 12-hour clock, zero-padded (01..12)
%lHour of the day, 12-hour clock, blank-padded (_1..12)
%PMeridian indicator, lowercase (am or pm)
%pMeridian indicator, uppercase (AM or PM)
%MMinute of the hour (00..59)
%SSecond of the minute (00..59)

Weekday Formatting

%AThe full weekday name (e.g. Sunday)
%^AThe full weekday name uppercased (e.g. SUNDAY)
%aThe abbreviated weekday name (e.g. Sun)
%^aThe abbreviated weekday name uppercased (e.g. SUN)
%uDay of the week starting Monday (1..7)
%wDay of the week starting Sunday (0..6)

Formatting Time Using to_fs

You may also use Ruby’s pre-existing time formats using to_fs or its alias to_formatted_s. to_fs converts time into a formatted string based on a predefined list of formats.

The code below shows the available time formats:

datetime = Time.now

datetime.to_fs(:db)            # => "2007-12-04 00:00:00"
datetime.to_fs(:number)        # => "20071204000000"
datetime.to_fs(:short)         # => "04 Dec 00:00"
datetime.to_fs(:time)          # => "06:16"
datetime.to_fs(:long)          # => "December 04, 2007 00:00"
datetime.to_fs(:long_ordinal)  # => "December 4th, 2007 00:00"
datetime.to_fs(:rfc822)        # => "Tue, 04 Dec 2007 00:00:00 +0000"
datetime.to_fs(:iso8601)       # => "2007-12-04T00:00:00+00:00"
datetime.to_fs(:nsec)          # => "20071204061645953133115"
datetime.to_fs(:usec)          # => "20071204061645953133"

The available predefined formats are limited. Luckily, you can add more time formats by adding new key-value pairs in Time::DATE_FORMATS hash.

#config/application.rb

#...
module App
  class Application < Rails::Application
    #...
+   Time::DATE_FORMATS.merge!(default: '%Y/%m/%d %I:%M %p', ymd: '%Y/%m/%d')
  end
end
#...

Restart your rails application and you can then use the formats you created.

datetime = Time.now

datetime.to_fs              # => "2007-12-04 00:00 AM" ->default
datetime.to_fs(:ymd)        # => "2007/12/04"

As you can see, without a parameter, to_fs will return the :default format.

You can now use this in your post index to change the time format of created_at instead of using strftime.

<!-- app/views/posts/index.html.erb -->
  
<!-- ... -->
<table>
  <!-- ... -->
  <% @posts.each do |post| %>
    <tr>
      <!-- ... -->
-     <td><%= post.created_at.strftime("%Y/%m/%d %I:%M %p") %></td>
+     <td><%= post.created_at.to_fs %></td>
      <!-- ... -->
    </tr>
  <% end %>
</table>
<!-- ... -->

Back to top

Copyright © 2020-2022 Secure Smarter Service, Inc. This site is powered by KodaCamp.