오늘 날짜가 날짜 범위에 속하는지 확인하는 방법은 무엇입니까?


81

내가 가진 이벤트가 start_timeend_time이벤트 "가 진행 중"인지 확인하고 싶습니다. 오늘 날짜가 두 날짜 사이의 범위에 있는지 확인하는 것입니다.

함수에서이 작업을 어떻게 수행합니까?

답변:


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


댓글 홍수 이후 업데이트 : 이 버전은 모든 곳에서 잘 작동합니다. (Rails, Ruby 1 및 Ruby 2에서) 이전 irb예제도 잘 작동했지만 일부 실험에서 대화 형 예제가 항상 올바르게 재현되지는 않았습니다. 이것은 잘라서 붙여 넣기가 더 쉽습니다.

이제 모두 정리되었습니다.


1
Ruby 1.8.7의 Rails 3에서는 작동하지 않으므로 @heathd 대답을 선호합니다.
Sandro L

3
TypeError 얻기 : 루비 2.0에서 시간에서 반복 할 수 없음
Pencilcheck

3
여기서 캐치는 무엇입니까? 다른 두 주석과 마찬가지로이 코드를 정확히 시도했는데 동일한 오류가 발생합니다. 왜 19 명이이 답변에 찬성 투표를 했나요? 작동 했나요? heathd의 대답은 나를 위해 작동합니다.
Ryan Sandridge

또한 나를 위해 작동하지 않습니다. 아마도 이전 버전에서 작동했지만 더 이상 나타나지 않습니다.
stuckj

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

좋은. 내가 필요한 것만. cover?방법을 알지 못함
Ryan Rebo 2015

1
이것도 함께 작동 Date합니다(Date.yesterday..Date.tomorrow).cover?(Date.today) => true
Amit Patel 2015

1
루비는 아름다워! .. 고마워!
Ele

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

날짜 클래스에는 Comparable 모듈이 포함되어 있으므로 모든 날짜 개체에는 between?메서드가 있습니다.

require 'date'

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

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

수업 시간도 마찬가지입니다.
adass apr

이것은 허용되는 답변보다 더 읽기 쉽습니다. +1 루비의 기능을 올바르게 사용하기 위해 :)
thutt

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?범위에 대한 방법입니다.


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

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를 반환하지만 대신 사용하겠습니다.
Tyler Rick

유효한 포인트. 내가 사용하기로 선택한 이유를 모르겠습니다.include_with_range범위가 범위와 비교되는 경우가 아니기 때문에 . 아마도 어떤 종류의 뇌종양 일 것입니다. @TylerRick에게 감사드립니다. @heathd 대답이 정말 최고입니다.
sorens

3

타임 스탬프 인 경우 :

def in_progress?
  (start_time..end_time) .include? (Time.now)
종료

1.9.2에서이 오류가 발생했습니다TypeError: can't iterate from Time
Benjamin Oakes

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.