今日の日付が日付範囲内にあるかどうかを知る方法は?


81

とのイベントがstart_timeありend_time、イベントが「進行中」かどうかを確認したいと思います。それは、今日の日付が2つの日付の間の範囲内にあるかどうかを確認することです。

関数でこれをどのように行いますか?

回答:


61

使用する ===


実際、これを行うオペレーターがいます。を作成し、演算子を使用してオブジェクトを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例も正常に機能しましたが、一部の実験ではインタラクティブな例が常に正しく再現されるとは限りませんでした。これはカットアンドペーストが簡単です。

今ではすべてがまっすぐになっています。


1
Ruby1.8.7のRails3では機能しないので、@ heathdの回答をお勧めします。
Sandro L

3
TypeErrorの取得:Ruby 2.0では時間から反復できません
Pencilcheck 2013年

3
ここでのキャッチは何ですか?他の2つのコメントと同様に、このコードを正確に試したところ、同じエラーが発生しました。なぜ19人がこの回答に投票したのですか?それは今までに機能しましたか?heathdの答えは私のために働きます。
ライアンサンドリッジ2013年

また、私にはうまくいきません。おそらくそれは古いバージョンで動作しましたが、もう表示されません。
stickj 2013年

2
注:これを機能させるには、日付を変換してから、それらが範囲内にあるかどうかを確認するために.to_i使用する必要があり===ます。IMO.coverage?は、日付のより良い解決策です。
エラー2017年

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

これは私がルビーについて好きなことです、あなたはいつもあなたのために仕事をする別の素晴らしい方法を発見します!
ダニエル2014

いいね。ちょうど私が必要なもの。cover?方法に気づいていなかった
ライアンレボ2015

1
これDateも同様に機能します(Date.yesterday..Date.tomorrow).cover?(Date.today) => true
Amit Patel 2015年

1
ルビーは美しいです!..ありがとう!
エレ2016年

===Ruby1.9.2では正常に動作します。あなたはただ忘れました.to_i
DigitalRoss 2016

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

日付クラスにはComparableモジュールが含まれているため、すべての日付オブジェクトにはbetween?メソッドがあります。

require 'date'

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

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

授業時間も。
adass 2017

これは、受け入れられた答えよりもはるかに読みやすいです。Rubyの力を正しく使用するための+1 :)
thutt 2018

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のネイティブインクルードと同じように動作しますか?方法。あなたの議論は別の範囲ではないので、このActiveSupport拡張機能は何の違いもありません。いずれにせよ、単にincludeを呼び出す必要がありますか?include_with_rangeではありませんか?include_with_range以降?単に含めるエイリアスですか?(alias_method_chainを使用)。
タイラーリック

a = DateTime.now; (a.beginning_of_day..a.end_of_day).include_with_range?(a)Rails 3.2.8およびruby-1.9.3-p194のコンソールで試してみると、false(trueではない)が返されます。(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
Benjamin Oakes 2012年

3

チェックされるのは、2つの日付の間の現在の日付です。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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.