Rails 8.2 adds this_week?, this_month?, and this_year? to Date and Time

· 3 min read

ActiveSupport already has today?, yesterday?, and tomorrow? on Date and Time. Rails 8.2 adds the next logical set: this_week?, this_month?, and this_year?.

Before

Checking whether a date falls within the current week, month, or year required range comparisons:

# Is this order from the current week?
order.placed_at.between?(Time.current.beginning_of_week, Time.current.end_of_week)

# Is this subscription expiring this month?
subscription.expires_on.between?(Date.current.beginning_of_month, Date.current.end_of_month)

# Is this event happening this year?
event.date.year == Date.current.year

Each check is readable enough on its own, but they add up quickly in controllers and views where you are branching on date ranges.

Rails 8.2

PR #55770 introduces three new predicate methods on Date and Time:

order.placed_at.this_week?           # true if within the current week
subscription.expires_on.this_month?  # true if within the current month
event.date.this_year?                # true if within the current year

They follow the same pattern as the existing predicates:

Date.current.this_week?   # => true
Date.current.this_month?  # => true
Date.current.this_year?   # => true

Date.yesterday.this_week? # => true (yesterday is still this week, usually)
Date.current.next_month.this_month? # => false

In controllers

def index
  @orders = Order.all
  @this_week_orders = @orders.select { |o| o.placed_at.this_week? }
  @this_month_orders = @orders.select { |o| o.placed_at.this_month? }
end

In views

<% if subscription.expires_on.this_month? %>
  <div class="warning">Your subscription expires this month.</div>
<% end %>

<% if report.generated_at.this_week? %>
  <span class="badge">Recent</span>
<% end %>

In scopes

class Order < ApplicationRecord
  scope :placed_this_week, -> { where(placed_at: Time.current.beginning_of_week..Time.current.end_of_week) }
  scope :placed_this_month, -> { where(placed_at: Time.current.beginning_of_month..Time.current.end_of_month) }
end

The predicate methods on instances complement these scopes when working with already-loaded records.

How to change the week boundary

this_week? uses Monday as the start of the week by default, consistent with ActiveSupport’s beginning_of_week. If your application configures a different week start, that is respected:

Date.beginning_of_week = :sunday
Date.current.beginning_of_week  # => last Sunday

Conclusion

this_week?, this_month?, and this_year? are small additions that remove a common category of boilerplate. They complete the set of readable date predicates that ActiveSupport has offered since Rails 3.

References

Prateek Choudhary
Prateek Choudhary
Technology Leader