← Blog

Date, DateTime, Time, and Time Zones in Ruby & Ruby on Rails

To Future Me (and anyone else who finds this useful):

I can never seem to remember which Ruby and Rails date and time methods use the system time zone, which use the Rails application time zone, and which return UTC. This is my reference for keeping them straight.


The short version


1. Calendar dates with Date

A Date contains a year, month, and day. It does not represent an instant in time and does not carry a time zone.

Date.parse("January 1 2025")
# => Wed, 01 Jan 2025
Date.new(2025, 2, 3)
# => Mon, 03 Feb 2025

# Omitting the day uses the first day of the month.
Date.new(2025, 2)
# => Sat, 01 Feb 2025

# Omitting the month and day uses January 1.
Date.new(2025)
# => Wed, 01 Jan 2025

Date.today is slightly different. It asks the system clock what today’s date is, so the result is determined using the system time zone:

Date.today
# => Wed, 01 Jan 2025

In Rails, use Date.current when “today” should be determined using the application’s configured time zone.


2. Ruby methods using the system time zone

Ruby’s core time methods do not know about Rails’ config.time_zone. They use the operating system’s local time zone.

Time.now
# => 2025-01-05 12:35:00.262441 -0600
DateTime.now
# => Sun, 05 Jan 2025 12:31:58 -0600

When DateTime.parse receives input without an explicit offset, it defaults to a fixed zero offset:

DateTime.parse("January 1 2025 10pm")
# => Wed, 01 Jan 2025 22:00:00 +0000

A zero offset is not the same thing as a named time zone with daylight-saving rules. For ordinary application timestamps, prefer Time and Rails’ ActiveSupport::TimeWithZone over DateTime.


3. Rails application time zone

Configure the application’s default time zone in application.rb:

class Application < Rails::Application
  config.time_zone = "Eastern Time (US & Canada)"
end

Rails’ current methods honor Time.zone when it is configured:

Time.current
# => Sun, 05 Jan 2025 13:50:39 EST -05:00

Date.current
# => Sun, 05 Jan 2025

DateTime.current
# => Sun, 05 Jan 2025 13:50:39 -0500

Date.yesterday and Date.tomorrow are relative to Date.current, so they also follow the Rails application time zone:

Date.yesterday
# => Sat, 04 Jan 2025

Date.tomorrow
# => Mon, 06 Jan 2025

Use Time.zone.parse when a timestamp without an offset should be interpreted in the application time zone:

Time.zone.parse("January 1 2025 10pm")
# => Wed, 01 Jan 2025 22:00:00 EST -05:00

When no Rails time zone is configured, the current methods fall back to the corresponding system-time methods.


4. Working explicitly with UTC

Call .utc when you specifically need a UTC value:

Time.now.utc
# => 2025-01-05 18:35:00.262441 UTC
Time.current.utc
# => 2025-01-05 18:50:39 UTC

To get the UTC calendar date for the current instant:

Time.now.utc.to_date
# => Sun, 05 Jan 2025

5. Converting between time zones

Use in_time_zone to represent an instant in another Rails time zone:

Time.now.utc.in_time_zone("Eastern Time (US & Canada)")
# => Sun, 05 Jan 2025 13:35:00 EST -05:00

Time.zone.now returns an ActiveSupport::TimeWithZone when a Rails time zone is configured:

Time.zone = "Hawaii"
Time.zone.now
# => Sun, 05 Jan 2025 10:04:16 HST -10:00

For a temporary override, prefer Time.use_zone so the previous zone is restored after the block:

Time.use_zone("Hawaii") do
  Time.current
end
# => Sun, 05 Jan 2025 10:04:16 HST -10:00

6. Formatting dates and times

Ruby’s strftime formats Date, Time, and DateTime values as strings.

time = Time.new(2025, 1, 5, 14, 16, 0)

time.strftime("%b %-d, %Y")
# => "Jan 5, 2025"

time.strftime("%A, %B %-d, %Y at %-I:%M%P")
# => "Sunday, January 5, 2025 at 2:16pm"

Weekday

Month

Day

Year

Hour

Minutes

Meridian indicator