How to know if today's date is in a date range?
I have an event with start_time
and end_time
and want to check if the event is "in progress". That would be to check if today's date is in the range between the two dates.
How would you do this in a function?
In Ruby 1.9.2 ===
doesn't work, I get an error:
irb(main):019:0> (Time.now .. (Time.now+1)) === Time.now
TypeError: can't iterate from Time
from (irb):19:in `each'
from (irb):19:in `include?'
from (irb):19:in `include?'
from (irb):19:in `==='
from (irb):19
from /opt/ruby192/bin/irb:12:in `<main>'
Instead use #cover?
:
irb(main):002:0> (Time.now..Time.now+4).cover?(Time.now)
=> true
irb(main):003:0> (Time.now..Time.now+4).cover?(Time.now+10)
=> false
Use ===
Actually, there is an operator that will do this. Make a Range
and compare Time
objects to it using the ===
operator.
start = Time.now.to_i
range = start..(start + 2)
inside = start + 1
outside = start + 3 # ok, now...
range === inside # true
range === outside # false
Update post-comment-flood: This version works well everywhere. (In Rails, in Ruby 1, and in Ruby 2.) The earlier
irb
example also worked fine but the interactive example wasn't always reproduced correctly in some experiments. This one is easier to cut-and-paste.
It's all straightened out now.
If you're using Rails you can use TimeWithZone#between?
. You'd then have something like this:
> start_time = Time.zone.parse('12pm') => Thu, 26 Jul 2012 12:00:00 EDT -04:00
> end_time = start_time + 1.hour => Thu, 26 Jul 2012 13:00:00 EDT -04:00
> inside = Time.zone.parse('12:30pm') => Thu, 26 Jul 2012 12:30:00 EDT -04:00
> outside = Time.zone.parse('1:30pm') => Thu, 26 Jul 2012 13:30:00 EDT -04:00
> inside.between?(start_time, end_time) => true
> outside.between?(start_time, end_time) => false
Because the date class includes the Comparable module, every date object has a between?
method.
require 'date'
today = Date.today
tomorrow = today + 1
one_month_later = today >> 1
tomorrow.between?(today, one_month_later) # => true
If you are using Rails, you could try this:
ruby-1.8.7-p299 :015 > a = DateTime.now
=> Fri, 02 Dec 2011 11:04:24 -0800
ruby-1.8.7-p299 :016 > (a.beginning_of_day..a.end_of_day).include_with_range? a
=> true
ruby-1.8.7-p299 :017 > (a.beginning_of_day..a.end_of_day).include_with_range? a+10.days
=> false
ruby-1.8.7-p299 :018 > (a.beginning_of_day..a.end_of_day).include_with_range? a+25.hours
=> false
ruby-1.8.7-p299 :019 > (a.beginning_of_day..a.end_of_day).include_with_range? a+2.hours
=> true
Note: I just used beginning_of_day
and end_of_day
to provide an easy range. The important part is the include_with_range?
method on a Range.