Dates & Times
Reviewed & published by Brayan K
Ruby handles moments in time with the built-in Time class and calendar days with the Date class from the standard library, both formatted with strftime.
Part of the free Ruby course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.
You'll read date parts, format with directives, parse strings, and do day and second arithmetic.
What You'll Learn in This Lesson
- Time.now and creating fixed Time values
- require 'date' for Date and DateTime
- Reading parts: year, month, day, hour, wday
- Formatting with strftime directives
- Parsing strings into dates
- Date arithmetic (days) and Time arithmetic (seconds)
1️⃣ Time Basics & Reading Parts
Time.now gives the current instant; Time.new(...) builds a specific one. Pull out parts with year, month, day, hour, min, and wday (0 = Sunday). We pin the offset to UTC so the output is identical every run.
require 'date'
# Use a FIXED date/time so output is reproducible.
# The "+00:00" pins the timezone offset to UTC.
t = Time.new(2026, 6, 18, 14, 30, 0, "+00:00")
puts t.year # 2026
puts t.month # 6
puts t.day # 18
puts t.hour # 14
puts t.min # 30
puts t.wday # 4 (0=Sunday ... 4=Thursday)
# Time.now would give the *current* time instead.
puts t # default text form2️⃣ Formatting with strftime & Parsing
strftime turns a date or time into any string layout using % directives — %Y year, %m month, %d day, %A weekday name, and more. Going the other way, Date.parse reads a string back into a Date.
require 'date'
d = Date.new(2026, 6, 18) # a Date has no time component
# strftime formats a date/time with directives:
puts d.strftime("%Y-%m-%d") # 2026-06-18
puts d.strftime("%A, %B %-d, %Y") # Thursday, June 18, 2026
puts d.strftime("%d/%m/%Y") # 18/06/2026
# Parse a string back into a Date:
parsed = Date.parse("2026-12-25")
puts parsed.strftime("%A") # Friday
# Time also supports strftime, including 24h time:
t = Time.new(2026, 6, 18, 9, 5, 0, "+00:00")
puts t.strftime("%H:%M") # 09:05
puts t.strftime("%I:%M %p") # 09:05 AM3️⃣ Date & Time Arithmetic
For a Date, + and - move by whole days, and subtracting two dates gives the gap between them. For a Time, the same operators move by seconds. Helpers like next_month handle calendar quirks for you.
require 'date'
start = Date.new(2026, 6, 18)
# Date arithmetic: + and - work in DAYS.
puts (start + 7).to_s # one week later
puts (start - 1).to_s # yesterday
# Difference between two dates (a Rational number of days):
deadline = Date.new(2026, 7, 1)
puts (deadline - start).to_i # days until deadline
# next_month / next_year helpers:
puts start.next_month.to_s
puts start.next_year.to_s
# Time arithmetic is in SECONDS:
t = Time.new(2026, 6, 18, 12, 0, 0, "+00:00")
later = t + 3600 # add one hour (3600 seconds)
puts later.strftime("%H:%M")Your turn. Count the days until a birthday and find which weekday it falls on. Fill in each ___.
require 'date'
# 🎯 YOUR TURN — replace each ___ then run with: ruby party.rb
birthday = Date.new(2026, 9, 1)
today = Date.new(2026, 6, 18)
# 1) How many days until the birthday? (subtract dates, then to_i)
days_left = (birthday - today).___
puts "#{days_left} days until the party"
# 2) What weekday does the birthday fall on?
puts birthday.strftime("___") # 👉 directive for the full weekday name
# ✅ Expected output:
# 75 days until the party
# TuesdayMini-Challenge: Event Countdown
Print a schedule that shows each event's formatted date, its weekday, and how many days away it is from a fixed "today". This combines formatting and date math. Run with ruby schedule.rb.
# 🎯 MINI-CHALLENGE: an event countdown.
# Save as schedule.rb and run with: ruby schedule.rb
#
# 1. require 'date'.
# 2. Build a hash of event name => Date (use fixed dates).
# 3. For each event, print its formatted date, weekday, and how
# many days from a fixed "today" it is.
#
# ✅ Example output:
# Launch: Jun 18 (Thursday), in 0 days
# Review: Jun 25 (Thursday), in 7 days
# Release: Jul 10 (Friday), in 22 days
# your code hereCommon Errors (and the fix)
- "uninitialized constant Date" — ❌ You forgot require 'date'. ✅ Add it (Time needs no require, Date does).
- Date difference looks weird — ❌ Subtracting dates yields a Rational. ✅ Call .to_i for whole days.
- Mixing up %m and %M — ❌ %m is month, %M is minutes. ✅ Lowercase = month, uppercase = minutes.
- Adding to a Time and expecting days — ❌ time + 1 adds one second. ✅ Add 86400 for a day, or use a Date.
Pro Tips
- 💡 ISO 8601: date.iso8601 gives the standard YYYY-MM-DD string for free.
- 💡 Remove padding: a hyphen like %-d drops the leading zero (so 5, not 05).
- 💡 Parsing is fuzzy: Date.parse is flexible but guesses; use Date.strptime(str, fmt) when the format is known.
📋 Quick Reference — Dates & Times
| Task | Ruby |
|---|---|
| Now | Time.now / Date.today |
| Build a date | Date.new(2026, 6, 18) |
| Format | d.strftime("%Y-%m-%d") |
| Parse | Date.parse("2026-12-25") |
| Add days | date + 7 |
| Days between | (b - a).to_i |
🎉 Lesson Complete!
- ✅ Time is built in; Date needs require 'date'
- ✅ Read parts with year, month, day, wday
- ✅ Format with strftime directives
- ✅ Parse strings with Date.parse
- ✅ Date math = days; Time math = seconds
Practice quiz
Which class requires `require 'date'` before you can use it?
- Time
- Integer
- Date
- String
Answer: Date. Time is built in, but Date (and DateTime) live in the standard library and need require 'date'.
What does `Date.new(2026, 6, 18) + 7` produce?
- A Date one week later (2026-06-25)
- A Date 7 months later
- A Time 7 seconds later
- An error
Answer: A Date one week later (2026-06-25). For a Date, + and - work in whole days, so +7 is one week later.
Subtracting two Date objects, e.g. `(b - a)`, returns what kind of value?
- An Integer of days
- A Time
- A String
- A Rational number of days
Answer: A Rational number of days. Date subtraction yields a Rational number of days; call .to_i for a plain integer.
Adding to a Time, e.g. `time + 3600`, moves it forward by how much?
- 3600 days
- 3600 seconds (one hour)
- 3600 minutes
- 3600 hours
Answer: 3600 seconds (one hour). Time arithmetic is in seconds, so + 3600 adds one hour.
Which strftime directive gives the full weekday name (e.g. 'Thursday')?
- %A
- %w
- %d
- %a
Answer: %A. %A is the full weekday name; %a is the abbreviated form and %d is the day of month.
What is the difference between %m and %M in strftime?
- No difference
- %m is minutes, %M is month
- %m is month, %M is minutes
- %m is military time
Answer: %m is month, %M is minutes. Lowercase %m is the month; uppercase %M is the minutes.
For `Time.new(2026, 6, 18, 14, 30, 0, '+00:00')`, what does `t.wday` return (0 = Sunday)?
- 3
- 4
- 5
- 6
Answer: 4. June 18, 2026 is a Thursday, and wday counts from 0=Sunday, so Thursday is 4.
What does `Date.parse("2026-12-25")` do?
- Formats a date into a string
- Returns the current date
- Raises an error
- Reads a string into a Date object
Answer: Reads a string into a Date object. Date.parse reads a string and returns a Date object.
Why did the lesson use fixed dates instead of Time.now?
- Time.now is deprecated
- So output is reproducible every run
- Time.now needs a require
- Fixed dates are faster
Answer: So output is reproducible every run. Time.now changes every run; fixed values keep example output identical and verifiable.
What does the directive prefix in %-d do compared with %d?
- Adds a leading zero
- Shows the weekday
- Removes the leading zero
- Uppercases the result
Answer: Removes the leading zero. A hyphen like %-d drops the zero-padding (5 instead of 05).
Continue this course
- Previous: Custom Exception Classes
- Next: JSON & YAML — Parse and generate JSON and YAML, and round-trip Ruby hashes
- Quick reference: Ruby cheat sheet
Frequently asked questions
What's the difference between Time, Date, and DateTime?
Time (built in, no require) models an instant down to fractions of a second and is timezone-aware — great for timestamps and durations. Date (require 'date') represents a calendar day with no time component, ideal for birthdays or deadlines. DateTime combines both but is largely legacy; modern Ruby code prefers Time for moments and Date for days. All three support strftime for formatting.
How does strftime work and where do the % directives come from?
strftime ('string format time') turns a date or time into a string using % directives: %Y is the 4-digit year, %m the zero-padded month, %d the zero-padded day, %A the full weekday name, %B the full month name, %H 24-hour, %I 12-hour, %M minutes, %p AM/PM. A hyphen like %-d removes zero-padding. These directives are shared with C and many other languages, so the knowledge transfers.
How do I do date arithmetic in Ruby?
For Date objects, + and - work in whole days: date + 7 is a week later, and subtracting two dates gives the number of days between them (as a Rational, so call .to_i for a plain integer). For Time objects, + and - work in seconds: time + 3600 adds an hour. There are also helpers like next_month, prev_day, and next_year for calendar-aware jumps.
Why did this lesson use fixed dates instead of Time.now?
Time.now and Date.today return the current moment, so their output changes every run — which makes examples impossible to verify. By constructing fixed values like Time.new(2026, 6, 18, 14, 30, 0, '+00:00') and pinning the UTC offset, every run produces identical output. In real programs you'd use Time.now or Date.today; for teaching and tests, deterministic fixed values are the way to go.