如何知道今天的日期是否在日期范围内?


81

我有一个活动,start_time并且end_time想要检查活动是否在“进行中”。那将是检查今天的日期是否在两个日期之间的范围内。

您将如何在函数中执行此操作?

Answers:


61

使用 ===


实际上,有一个操作员可以做到这一点。制作一个RangeTime然后使用===运算符将其与对象进行比较。

start   = Time.now.to_i

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

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


更新评论后洪灾:此版本在任何地方都适用。(在Rails,Ruby 1和Ruby 2中。)前面的irb示例也很好用,但是在某些实验中,交互示例并非总是正确地再现。这个更容易剪切和粘贴。

现在一切都理顺了。


1
在Ruby 1.8.7的Rails 3中不起作用,所以我更喜欢@heathd答案。
Sandro L

3
收到TypeError:在ruby 2.0中无法从时间进行迭代
Pencilcheck 2013年

3
这里有什么收获?像其他两个注释一样,我完全尝试了此代码,并得到相同的错误。为什么有19个人对此投票赞成?它曾经奏效吗?heathd的回答对我有用。
瑞安·桑德里奇

也对我不起作用。也许它可以在较旧的版本中工作,但现在似乎不再存在。
stickj 2013年

2
注意:为此,您需要转换日期.to_i,然后再使用===它们来查看它们是否在范围内。IMO,.coverage?是一个更好的日期解决方案。
错误的

246

在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

这就是我对红宝石的热爱,您总是会发现另一种为您工作的出色方法!
丹尼尔(Daniel)2014年

真好 正是我所需要的。不知道该cover?方法
Ryan Rebo 2015年

1
这适用于Date以及(Date.yesterday..Date.tomorrow).cover?(Date.today) => true
阿米特·帕特尔

1
露比很漂亮!
Ele 2016年

===在Ruby 1.9.2中可以正常工作。您只是忘记了.to_i
DigitalRoss

37

如果您使用的是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

17

因为date类包含Comparable模块,所以每个date对象都有一个between?方法。

require 'date'

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

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

上课时间也是如此。
adass

这比接受的答案更具可读性。+1,以正确使用Ruby的能力:)
thutt '18

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_dayend_of_day提供一个简单的范围。重要的部分是include_with_range?范围上的方法。


看起来像Range#include_with_range吗?ActiveSupport提供的方法仅使用#include?添加一个功能检查,如果一个范围包括另一个范围,例如:(1..5).include?(1..5)。除此之外,它的行为与Ruby的本地include相同吗?方法。由于您的论点不在另一个范围内,因此此ActiveSupport扩展应该没有任何区别。无论如何,您应该简单地调用include?而不是include_with_range?因为include_with_range?只是要包含的别名?(使用alias_method_chain)。
泰勒里克(Tyler Rick)2012年

一个= DateTime.now; (a.beginning_of_day..a.end_of_day).include_with_range?(a)在Rails 3.2.8和ruby-1.9.3-p194中的控制台中为我返回false(不是真的)。(a.beginning_of_day..a.end_of_day).cover?(a)返回true,但是,我只使用它。
泰勒·里克

一个有效的点。不知道为什么选择使用,include_with_range因为这不是将范围与范围进行比较的情况。可能是某种脑瘤。好的收获,谢谢@TylerRick。@heathd答案的确是最好的答案。
sorens 2012年

3

如果是时间戳记:

def in_progress?
  (start_time..end_time).include?(Time.now)
结束

对我而言,1.9.2产生了错误TypeError: can't iterate from Time
本杰明·奥克斯

3

检查的是两个日期之间的当前日期。使用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

2

概要

  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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.