Bugünün tarihinin bir tarih aralığında olup olmadığını nasıl anlarım?


81

İle bir etkinliğim var start_timeve end_timeolayın "devam ediyor" olup olmadığını kontrol etmek istiyorum. Bu, bugünün tarihinin iki tarih arasındaki aralıkta olup olmadığını kontrol etmek olacaktır.

Bunu bir işlevde nasıl yaparsınız?

Yanıtlar:


61

Kullanım ===


Aslında bunu yapacak bir operatör var. Operatörü kullanarak bir yapın Rangeve Timenesneleri onunla karşılaştırın ===.

start   = Time.now.to_i

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

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


Yorum sonrası sel güncelleme: Bu sürüm her yerde iyi çalışır. (Rails'de, Ruby 1'de ve Ruby 2'de) Önceki irbörnek de iyi çalıştı ancak etkileşimli örnek bazı deneylerde her zaman doğru şekilde yeniden üretilmedi. Bunu kesip yapıştırmak daha kolay.

Şimdi her şey düzeldi.


1
Ruby 1.8.7'deki Rails 3'te çalışmıyor, bu yüzden @heathd cevabını tercih ediyorum.
Sandro L

3
TypeError Alma: Ruby 2.0'da
zamandan beri yinelenemiyor

3
Burada yakalama nedir? Diğer iki yorum gibi, bu kodu tam olarak denedim ve aynı hatayı alıyorum. Neden 19 kişi bu cevabı oyladı? Hiç işe yaradı mı? Heathd'in cevabı benim için çalışıyor.
Ryan Sandridge

Benim için de çalışmıyor. Belki daha eski bir sürümde işe yaradı, ancak artık görünmüyor.
2013

2
Not: Bunun çalışması için, tarihleri ​​dönüştürmeniz .to_ive ardından ===aralıkta olup olmadıklarını görmek için kullanmanız gerekir. IMO, .coverage?tarihler için daha iyi bir çözümdür.
erroric

246

Ruby 1.9.2'de ===çalışmıyor, bir hata alıyorum:

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

Bunun yerine şunu kullanın #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

Ruby hakkında sevdiğim şey bu, her zaman sizin için işi yapan başka bir harika yöntem keşfedersiniz!
daniel

Güzel. Tam ihtiyacım olan şey. cover?Yöntemin farkında değildi
Ryan Rebo

1
Bu Dateaynı zamanda çalışır(Date.yesterday..Date.tomorrow).cover?(Date.today) => true
Amit Patel

1
Ruby güzeldir! .. Teşekkürler!
Ele

===Ruby 1.9.2'de iyi çalışıyor. Sadece unuttunuz.to_i
DigitalRoss

38

Rails kullanıyorsanız kullanabilirsiniz TimeWithZone#between?. Daha sonra şuna benzer bir şeye sahip olursunuz:

> 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

Tarih sınıfı Comparable modülünü içerdiğinden, her tarih nesnesinin bir between?yöntemi vardır.

require 'date'

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

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

Sınıf Saati de.
adass

Bu, kabul edilen cevaptan çok daha okunaklı. Ruby'nin güçlerini doğru kullanmak için +1 :)
2018

5

Rails kullanıyorsanız, şunu deneyebilirsiniz:

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 

Not: Sadece kullandım beginning_of_dayve end_of_daykolay bir aralık sağlamak için. Önemli olan include_with_range?, bir Aralıktaki yöntemdir.


Aralık # include_with_range? ActiveSupport tarafından sağlanan yöntem, bir aralık #include? kullanarak başka bir aralık içeriyorsa, yetenek kontrolü ekler, örneğin: (1..5) .include? (1..5). Bunun dışında, Ruby'nin yerli dahil etme ile aynı şekilde davranır? yöntem. Bağımsız değişkeniniz başka bir aralık olmadığından, bu ActiveSupport uzantısı hiçbir fark yaratmamalıdır. Her durumda, basitçe include'i aramalısınız? ve include_with_range değil mi? include_with_range'den beri? sadece eklenecek bir takma ad mı? (alias_method_chain kullanarak).
Tyler Rick

a = DateTime.now; (a.beginning_of_day..a.end_of_day) .include_with_range? (a) Rails 3.2.8 ve ruby-1.9.3-p194'te konsolda denediğimde benim için yanlış (doğru değil) döndürüyor. (a.beginning_of_day..a.end_of_day) .cover? (a) true döndürür, bu yüzden onun yerine onu kullanacağım.
Tyler Rick

geçerli bir nokta. include_with_rangeBir aralığın bir aralıkla karşılaştırıldığı bir durum olmadığı için neden kullanmayı seçtiğimden emin değilim . Muhtemelen bir tür beyin tümörü. İyi yakaladım, teşekkürler @TylerRick. @heathd cevabı gerçekten en iyisidir.
sorens

3

Zaman damgasıysa:

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

1.9.2'de benim için bu bir hata verdiTypeError: can't iterate from Time
Benjamin Oakes

3

Kontrol edilen iki tarih arasındaki geçerli tarihtir. Ruby kullanmak

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

3

özet

  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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.