Как узнать, находится ли сегодня дата в диапазоне дат?

У меня есть событие с start_time и end_time и вы хотите проверить, не произошло ли событие. Это будет проверять, находится ли сегодня дата в диапазоне между двумя датами.

Как вы это сделаете в функции?

Ответ 1

Используйте ===


Собственно, есть оператор, который сделает это. Сделайте Range и сравните с ним объекты Time с помощью оператора ===.

start   = Time.now.to_i

range   = start..(start + 2)
inside  = start + 1
outside = start + 3        # ok, now...

range === inside  # true
range === outside # false


Обновление post-comment-flood: эта версия хорошо работает везде. (В Rails, Ruby 1 и Ruby 2.) Более ранний пример irb также работал нормально, но интерактивный пример не всегда воспроизводился правильно в некоторых экспериментах. Это проще для вырезания и вставки.

Теперь все выпрямилось.

Ответ 2

В Ruby 1.9.2 === не работает, я получаю сообщение об ошибке:

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>'

Вместо этого используйте #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

Если вы используете Rails, вы можете использовать TimeWithZone#between?. У вас было бы что-то вроде этого:

> 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

Поскольку класс даты включает модуль Comparable, каждый объект даты имеет метод between?.

require 'date'

today           = Date.today
tomorrow        = today + 1
one_month_later = today >> 1

tomorrow.between?(today, one_month_later) # => true

Ответ 5

Если вы используете Rails, вы можете попробовать следующее:

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 

Примечание. Я использовал beginning_of_day и end_of_day, чтобы обеспечить легкий диапазон. Важной частью является метод include_with_range? в диапазоне.

Ответ 6

Если это временные метки:

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