How to know if today's date is in a date range

2019-01-20 22:48发布

问题:

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?

回答1:

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.



回答2:

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


回答3:

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


回答4:

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


回答5:

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.



回答6:

If they're timestamps:

def in_progress?
  (start_time..end_time).include?(Time.now)
end


回答7:

Checked is current date in between two dates. Using Ruby

currentDate = DateTime.now
start_date = "2017-03-31"
end_date = "2018-03-31"
currentDate.between?(start_date, end_date)

**Out Put Will be** true or false


回答8:

summary

  d1      = DateTime.parse('2018/04/01')
  d2      = DateTime.parse('2018/04/29')
  outside = DateTime.parse('2018/04/30')
  inside  = DateTime.parse('2018/04/15')

  # include?
  (d1...d2).include?(d1)      # true
  (d1...d2).include?(d2)      # false
  (d1...d2).include?(outside) # false
  (d1...d2).include?(inside)  # true

  (d1..d2).include?(d1)      # true
  (d1..d2).include?(d2)      # true
  (d1..d2).include?(outside) # false
  (d1..d2).include?(inside)  # true

  # ===
  (d1...d2) === d1      # true
  (d1...d2) === d2      # false
  (d1...d2) === outside # false
  (d1...d2) === inside  # true

  (d1..d2) === d1      # true
  (d1..d2) === d2      # true
  (d1..d2) === outside # false
  (d1..d2) === inside  # true

  # cover?
  (d1...d2).cover?(d1)      # true
  (d1...d2).cover?(d2)      # false
  (d1...d2).cover?(outside) # false
  (d1...d2).cover?(inside)  # true

  (d1..d2).cover?(d1)      # true
  (d1..d2).cover?(d2)      # true
  (d1..d2).cover?(outside) # false
  (d1..d2).cover?(inside)  # true

  # between?
  d1.between?(d1, d2)       # true
  d2.between?(d1, d2)       # true
  outside.between?(d1, d2)  # false
  inside.between?(d1, d2)   # true


标签: ruby date range