2011-05-04 6 views
11

몇 달 간의 차이를 어떻게 계산합니까? 또한 차이가 발생하면 DateTime이 아닌 Date 객체로 작업하고 있습니다. 또한 일부 반올림 옵션은 좋을 수도 있으므로 부분 개월을 반올림하거나 반올림하려는 경우 제어 할 수 있습니다.레일은 월별 날짜 범위를 계산합니다

감사합니다. 이는 오케이를 제공해야합니다

http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html#method-i-distance_of_time_in_words

+0

나는 이것을 좋아하지만 코드 작성이 다소 번거롭다. ._. – omninonsense

+0

DateTime과 Date는 'DateTime # to_date'및 'Date # to_datetime' 메소드를 사용하여 다소 상호 교환 가능합니다. – tadman

+0

아마, [년 정도의 비슷한 질문] (http://stackoverflow.com/questions/1904097/how-to-calculate-how-many-years-passed-since-a-given-date-in-ruby) 도와 드릴까요? –

답변

9

는 분수로 일수를 산출 할 것이다으로부터 다른 날짜 또는 날짜를 감산했지만 필요에 따라이 Float 또는 Fixnum A와 평가 될 수있다. 예를 들어

는 :

(Date.today - Date.today.advance(:months => -3)).to_f 
# => 89.0 

오늘과 3 개월 전에 같은 달력 날짜 사이 89.0 일이 있었다. 평균 30 일 또는 30.4375를 사용하여 작업하는 경우, 현재와 현재 사이에 2.92 개월이 경과하거나 가장 가까운 정수 3으로 반올림됩니다.

정확한 월별 달력 수는 까다 롭지 만 수행 할 수 있습니다. 이 같은

+0

달력 개월이 선호 될 것입니다 ...하지만 너무 까다로운 경우 30 (또는 30.44) 바이트로 나누기 만하면됩니다. – brettish

+0

당신은 조금 더 생각해보고 어떻게 캘린더 개월을 구현하려고 시도했는지 알기에 그만한 가치가 있다고 판단했습니다. 당신의 접근 방식을 사용하겠습니다. – brettish

0

이 기능을위한 레일 도우미가 근사 :

Date1 - Date2 = difference_in_days 
(difference_in_days/30).round = difference_in_months 
+0

머리를 주셔서 감사합니다. .. 나는 그것을 계산할 수있는 숫자를 찾고있다. 그러나 이것은 다른 곳에서도 유용 할 것이다! – brettish

5

:

+0

달력 달 접근 방식이 가치가 있기에 너무 까다로운 경우 그래도 할 수 있습니다. – brettish

+1

좀 더 정확한 결과를 얻으려면 'round'를 'floor'로 변경하고 싶을 수도 있습니다. – yalestar

5

뭔가 초를 알아내는 것보다 더 읽기, 그리고 당신에게 실제 달력 차이를 줄 것이다 : 당신은뿐만 아니라 일에 따라 차이를 해결해야하는 경우

# Calculate differnce between two dates in months 
# Produces b - a 
def month_difference(a, b) 
    difference = 0.0 
    if a.year != b.year 
     difference += 12 * (b.year - a.year) 
    end 
    difference + b.month - a.month 
end 

하면, 당신은 단지에 따라 수 패턴

+0

와우, 고마워! 유용한 코드 덩어리입니다. 메서드의 처음 4 줄을'difference = 12 * (b.year - a.year) .abs' (.abs와 함께 사용하면 날짜가 어떤 순서인지는 중요하지 않습니다. 에서 지정) – brettish

+0

@brettish 그렇지 않으면 함수가 방향 정보를 버려야하므로 함수의 바깥쪽에 abs를 유지합니다. 또한 a.year> b.year하지만 a.month Glenjamin

+1

더 깨끗한 버전이 있습니다 [여기] (http://stackoverflow.com/questions/9428605/find-number-of-months-between-two-dates-in-ruby-on-rails) : (date2.year * 12 + date2.month) - (date1.year * 12 + date1.month) –

5

우리는이 라인을 따라 뭔가가 필요했지만, 부분적인 월을 포함했습니다. 따라서 1/31에서 2/1까지 2 개월이 걸릴 것입니다. 도움이 될지도!

def self.month_count(range) 
    12 * (range.end.year - range.begin.year) + range.end.month - range.begin.month 
end 
0

어떨까요?

current_date = start_date 

while current_date < end_date 
    # something 
    current_date = current_date.next_month 
end 
1

이 대답은하지만, 그것은 계정에 일을 복용 두 날짜 사이의 달력 차이를 준다, 파티에 늦은 이전의 답변을 바탕으로, 그리고 아마도 더 간결하게 작성할 수 있습니다.

def difference_in_months(start_date, today) 
    date_to_months(today) - date_to_months(start_date) + adjustment_for_days(start_date, today) 
end 

def date_to_months(date) 
    date.year * 12 + date.month 
end 

def adjustment_for_days(earlier_date, later_date) 
    if later_date.day == earlier_date.day 
    0 
    elsif later_date.day > earlier_date.day 
    1 
    else 
    -1 
    end 
end 
0

두 날짜 사이에 정확한 월 (십진수 포함)이 필요했고 다음과 같은 방법으로 작성했습니다.

def months_difference(period_start, period_end) 
    period_end = period_end + 1.day 
    months = (period_end.year - period_start.year) * 12 + period_end.month - period_start.month - (period_end.day >= period_start.day ? 0 : 1) 
    remains = period_end - (period_start + months.month) 

    (months + remains/period_end.end_of_month.day).to_f.round(2) 
end 

9 월 26 일부터 9 월 26 일까지 (당일) 비교하면 1 일로 계산됩니다. 당신이 방법의 첫 번째 라인을 제거 할 수 필요가없는 경우 : period_end = period_end + 1.day

그것은 다음과 같은 사양을 전달합니다

expect(months_difference(Date.new(2017, 8, 1), Date.new(2017, 8, 31))).to eq 1.0 
expect(months_difference(Date.new(2017, 8, 1), Date.new(2017, 8, 30))).to eq 0.97 
expect(months_difference(Date.new(2017, 8, 1), Date.new(2017, 10, 31))).to eq 3.0 
# Overlapping february (28 days) still counts Feb as a full month 
expect(months_difference(Date.new(2017, 1, 1), Date.new(2017, 3, 31))).to eq 3.0 
expect(months_difference(Date.new(2017, 2, 10), Date.new(2017, 3, 9))).to eq 1.0 
# Leap year 
expect(months_difference(Date.new(2016, 2, 1), Date.new(2016, 2, 29))).to eq 1.0 

그것은 레일 'ActiveSupport에 의존한다.

관련 문제