class Date

Practical examples and pitfalls for Date

Date examples: parse calendar input and handle month ends

Practical notes by Ruby-Doc.org

Use the date format in the input contract

A form can ask for a calendar date without asking for a clock time. Fields that use calendars (dates) do not imply a specific time zone. When you want to know about a particular day (like the start or finish date of a report), treat them as just dates until you get some indication otherwise. In this example, Date.iso8601 reads an ISO-formatted string, and the arithmetic works with calendar days.

Example 1
require "date"
day = Date.iso8601("2026-09-10")
puts day + 7
p (day + 7) - day
Expected output
2026-09-17
(7/1)

If the date is invalid, handle the parsing failure with an error the caller can understand. Do not substitute today's date for a value that did not successfully parse; because if someone has an older or malformed request, they would see it as being current. A test using a fixed input allows you to reproduce the problem of parsing without relying on the system clock.

Define what shifting a month should mean

A day near the end of one month may not exist in the next month. Ruby's month-shift operation adjusts to a valid day in the destination month. In the January example, shifting one month twice therefore gives a different result from shifting the original date two months.

Example 2
require "date"
anchor = Date.new(2026, 1, 31)
puts anchor >> 1
puts (anchor >> 1) >> 1
puts anchor >> 2
Expected output
2026-02-28
2026-03-28
2026-03-31

The differences in these shifts matter for creating schedules for a month. If all occurrences need to be based off of the original anchor, hold onto that anchor and calculate each occurrence using its month offset from that anchor. If the schedule simply states that every month needs to include the last day of the month, state that instead of repeatedly shifting something after adjusting it.

Test date arithmetic independently

Use both a year that has a leap day and a year that doesn’t as part of your test cases. Create an anchor from the end-of-the-month and create another anchor from the middle-of-the-month. These allow you to ask different questions about your schedule, but should not be combined into a single “happy path” test.

A Date calculation does not choose a timezone or a time of day. If the application later needs a Time, make those choices explicit at the conversion step. Keeping the two calculations separate helps distinguish an error in the calendar rule from an error in the instant at which an event is due.

API reference: Date API reference

Related: Time · Range

Class Date provides methods for storing and manipulating calendar dates.

Consider using class Time instead of class Date if:

A Date object, once created, is immutable, and cannot be modified.

Creating a Date

You can create a date for the current date, using Date.today:

Date.today # => #<Date: 1999-12-31>

You can create a specific date from various combinations of arguments:

See also the specialized methods in “Specialized Format Strings” in Formats for Dates and Times

Argument limit

Certain singleton methods in Date that parse string arguments also take optional keyword argument limit, which can limit the length of the string argument.

When limit is: