Ruby Date & Time
Date & Time in Ruby
Section titled “Date & Time in Ruby”Ruby provides robust support for handling dates and times through its core Time class and the standard library Date and DateTime classes (found in the date library, which may need to be require’d for Date and DateTime). The Time class represents a specific moment in time, including both date and time components, down to microsecond precision on most modern systems.
On modern 64-bit systems, Ruby’s Time objects can represent a very wide range of dates, far exceeding the old 1970-2038 limitations that affected some older 32-bit systems.
Getting Current Date and Time
Section titled “Getting Current Date and Time”You can get the current system date and time using Time.now or its alias Time.new (when called without arguments).
#!/usr/bin/env ruby
time_now = Time.nowputs "Current Time (Time.now): #{time_now.inspect}"
# Time.new is an alias for Time.now when called without argumentstime_new = Time.newputs "Current Time (Time.new): #{time_new.inspect}"This will produce output similar to (the exact time and timezone will vary):
Current Time (Time.now): 2023-10-27 10:30:45.123456 -0700Current Time (Time.new): 2023-10-27 10:30:45.123456 -0700Components of a Time Object
Section titled “Components of a Time Object”A Time object provides methods to access its various components:
#!/usr/bin/env ruby
time = Time.now
puts "Current Time: #{time.inspect}"puts "Year: #{time.year}" # e.g., 2023puts "Month: #{time.month}" # 1 (January) to 12 (December)puts "Day: #{time.day}" # 1 to 31puts "Hour: #{time.hour}" # 0 to 23 (24-hour clock)puts "Minute: #{time.min}" # 0 to 59puts "Second: #{time.sec}" # 0 to 59 (can be 60 for leap second)puts "Microsecond: #{time.usec}" # 0 to 999999puts "Nanosecond: #{time.nsec}" # 0 to 999999999 (more precise than usec)puts "Day of week (wday): #{time.wday}" # 0 (Sunday) to 6 (Saturday)puts "Day of year (yday): #{time.yday}" # 1 to 365 (or 366 in a leap year)puts "Timezone: #{time.zone}" # e.g., "PST", "UTC", "EDT" (may be nil)puts "Is DST?: #{time.dst?}" # true if Daylight Saving Time is in effectCreating Time Objects for Specific Dates/Times
Section titled “Creating Time Objects for Specific Dates/Times”You can create Time objects for specific dates and times using:
Time.local(year, month, day, hour, min, sec, usec_with_frac)orTime.mktime(...): Creates aTimeobject in the system’s local timezone.Time.utc(year, month, day, hour, min, sec, usec_with_frac)orTime.gm(...): Creates aTimeobject in Coordinated Universal Time (UTC), also known as Greenwich Mean Time (GMT).
#!/usr/bin/env ruby
# December 25, 2025, 14:30:00 local timelocal_time = Time.local(2025, 12, 25, 14, 30, 0)puts "Local Time: #{local_time.inspect}"
# July 4, 2024, 09:15:00 UTCutc_time = Time.utc(2024, 7, 4, 9, 15, 0)puts "UTC Time: #{utc_time.inspect}"
# You can omit parts from right to left; they default to minimum values (e.g., 1 for month/day, 0 for time components)start_of_year = Time.local(2023) # January 1, 2023, 00:00:00 local timeputs "Start of 2023: #{start_of_year.inspect}"Time Object Conversions
Section titled “Time Object Conversions”Time objects can be converted to various other representations:
time.to_a: Returns a 10-element array:[sec, min, hour, day, month, year, wday, yday, isdst, zone_abbreviation].time.to_iortime.tv_sec: Returns the number of seconds since the Unix epoch (January 1, 1970, 00:00:00 UTC).time.to_fortime.tv_useccombined withtv_sec: Returns seconds since epoch as a float, including microseconds.Time.at(seconds_since_epoch): Creates aTimeobject from the number of seconds since the epoch.
#!/usr/bin/env ruby
time = Time.now
components_array = time.to_aputs "Time as array: #{components_array.inspect}"# Example: [15, 30, 10, 27, 10, 2023, 5, 300, true, "PDT"]
seconds_epoch = time.to_iputs "Seconds since epoch: #{seconds_epoch}"
reconstructed_time = Time.at(seconds_epoch)puts "Reconstructed time from seconds: #{reconstructed_time.inspect}"Timezones and Daylight Saving Time (DST)
Section titled “Timezones and Daylight Saving Time (DST)”Ruby’s Time objects are timezone-aware. You can convert between timezones:
#!/usr/bin/env ruby
time = Time.now # Created in local timezone
puts "Original (local): #{time.inspect} (Zone: #{time.zone}, DST: #{time.dst?})"
# Convert to UTCutc_time = time.utcputs "UTC: #{utc_time.inspect} (Zone: #{utc_time.zone}, DST: #{utc_time.dst?})"
# Convert UTC time back to local timezonelocal_again = utc_time.localtimeputs "Local again: #{local_again.inspect} (Zone: #{local_again.zone}, DST: #{local_again.dst?})"
# Get a new Time object in UTC or local zone without modifying originalnew_utc_obj = time.getutcnew_local_obj = utc_time.getlocal
puts "Is original time UTC? #{time.utc?}" # false (if local time is not UTC)puts "Is utc_time object UTC? #{utc_time.utc?}" # true
puts "UTC offset: #{time.utc_offset} seconds" # e.g., -25200 for PDT (-7 hours)Formatting Times and Dates with strftime
Section titled “Formatting Times and Dates with strftime”The strftime (string format time) method is powerful for custom formatting of Time objects into strings. It uses directives (percent-prefixed characters) to specify how each part of the time should be represented.
#!/usr/bin/env ruby
time = Time.now
puts "Default to_s: #{time.to_s}" # e.g., 2023-10-27 10:30:45 -0700puts "ctime: #{time.ctime}" # e.g., Fri Oct 27 10:30:45 2023puts "ISO 8601: #{time.iso8601}" # e.g., 2023-10-27T10:30:45-07:00
puts "Custom format (YYYY-MM-DD HH:MM:SS): #{time.strftime("%Y-%m-%d %H:%M:%S")}"puts "Custom format (Month Day, Year): #{time.strftime("%B %d, %Y")}"puts "Custom format (hh:mm AM/PM Zone): #{time.strftime("%I:%M %p %Z")}"Common strftime Directives:
Section titled “Common strftime Directives:”| Directive | Description |
|---|---|
%Y | Year with century (e.g., 2023) |
%y | Year without century (00-99) |
%m | Month of the year (01-12) |
%B | Full month name (e.g., January) |
%b or %h | Abbreviated month name (e.g., Jan) |
%d | Day of the month (01-31) |
%e | Day of the month, space-padded ( 1-31) |
%A | Full weekday name (e.g., Sunday) |
%a | Abbreviated weekday name (e.g., Sun) |
%w | Day of the week (Sunday is 0, 0-6) |
%H | Hour of the day, 24-hour clock (00-23) |
%I | Hour of the day, 12-hour clock (01-12) |
%M | Minute of the hour (00-59) |
%S | Second of the minute (00-60) (60 for leap second) |
%L | Millisecond of the second (000-999) |
%N | Nanosecond of the second (000000000-999999999) |
%p | Meridian indicator (AM or PM) |
%Z | Time zone abbreviation name |
%z | Time zone offset from UTC (e.g., +0900, -0700) |
%:z | Time zone offset with colon (e.g., +09:00) |
%c | Locale-specific date and time (e.g., Fri Oct 27 10:30:45 2023) |
%x | Locale-specific date representation (e.g., 10/27/23) |
%X | Locale-specific time representation (e.g., 10:30:45) |
%% | A literal ’%’ character |
Time Arithmetic
Section titled “Time Arithmetic”You can perform arithmetic with Time objects. Adding or subtracting a numeric value treats that number as seconds.
#!/usr/bin/env ruby
now = Time.nowputs "Current time: #{now}"
one_hour_ago = now - 3600 # 3600 seconds = 1 hourputs "One hour ago: #{one_hour_ago}"
two_days_from_now = now + (2 * 24 * 60 * 60) # Add seconds for 2 daysputs "Two days from now: #{two_days_from_now}"
difference = two_days_from_now - now # Difference between two Time objects is in seconds (float)puts "Difference in seconds: #{difference}"puts "Difference in days: #{difference / (24 * 60 * 60)}"Output (example):
Current time: 2023-10-27 10:45:00 -0700One hour ago: 2023-10-27 09:45:00 -0700Two days from now: 2023-10-29 10:45:00 -0700Difference in seconds: 172800.0Difference in days: 2.0Using Date and DateTime for Date-Specific Operations
Section titled “Using Date and DateTime for Date-Specific Operations”For operations that are primarily date-focused (without time components) or require historical date calculations (e.g., Julian/Gregorian calendar reforms), the Date and DateTime classes from the date standard library are often more suitable. You need to require 'date' to use them.
#!/usr/bin/env rubyrequire 'date'
today = Date.todayputs "Today (Date): #{today.inspect}" # e.g., #<Date: 2023-10-27 ((2460245j,0s,0n),+0s,2299161j)>puts "Formatted Date: #{today.strftime('%A, %B %d, %Y')}"
yesterday = today - 1puts "Yesterday: #{yesterday}"
next_month = today >> 1 # Add one monthputs "Next month: #{next_month}"
# DateTime includes time componentsdt_now = DateTime.nowputs "DateTime now: #{dt_now.inspect}"For detailed information, refer to the official Ruby documentation for Time, Date, and DateTime.