Ruby on Rails에서 두 날짜 사이의 개월 수 찾기


95

두 개의 Ruby on Rails DateTime 개체가 있습니다. 그들 사이의 개월 수를 찾는 방법은 무엇입니까? (다른 해에 속할 수 있음을 명심하십시오)


5
질문과 답이 여기 있었 : stackoverflow.com/questions/5887756/...
팀 BAAS을

지적 해 주셔서 감사합니다. 나는 수색했지만 우연히 발견하지 못했습니다.
phoenixwizard 2012


차라리 숫자로 된 링크를 원합니다. 나는이 방법에 의해 수행되었다은 마시밀리아노 Peluso에 의해 참조
phoenixwizard

그냥 내가 어쨌든 .. .. 참조를 위해 감사를 준
sangeethkumar

답변:


179
(date2.year * 12 + date2.month) - (date1.year * 12 + date1.month)

http://www.ruby-forum.com/topic/72120 에서 자세한 정보


25
이 솔루션은 며칠을 고려하지 않습니다. 2000
4

15
날을 고려하지 않고 필요하므로 이것이 나를 위해 작동합니다. +1
WattsInABox 2013 년

1
이 훌륭한 답변에 대한 또 다른 변형 :(12 * (date2.year - date1.year) + date2.month - date1.month).abs if date1 && date2
Stepan Zakharov

2 년, 즉 2017-05-20에서 2018-05-20 사이의 개월을 가져 오려고하면 잘못된 개월 수가 표시됩니다. 출력은 1 개월을 표시합니다.
호기심 개발자

1
@CuriousDeveloper 올바른 달을 보여줍니다. 즉 12
ts

40

더 정확한 답은 멀리있는 날을 고려할 것입니다.

당신의 달 거리 것을 고려하는 경우 예를 들어, 28/4/20001/5/2000입니다 0보다는 1, 당신은 사용할 수 있습니다 :

(date2.year - date1.year) * 12 + date2.month - date1.month - (date2.day >= date1.day ? 0 : 1)

1
예 : 누군가가 월급을받은 횟수를 계산하기 위해 항상
Matthias

15

시도해보십시오

((date2.to_time - date1.to_time)/1.month.second).to_i

irb>Time.at("2014-10-01".to_time - "2014-12-01".to_time).month => 10 (나는 ... 포맷에 포기를 알아낼 수 없습니다)
토비 소목에게

Date 객체를 사용하더라도 @ toby-joiner의 주석은 여전히 ​​정확합니다. 그 이유는 <10 월>-<12 월>은 -2 개월이지만 Time.at (-2months) .month는 -2에 해당하는 월을 제공합니다 (예 : -2 % 12 # => 10). 제안 된 방법은 두 달이 서로 이어지고 1 년 미만의 간격이있는 경우 작동하지만 두 달이 역순 (예 : 10 월-12 월)이거나 두 달이 1 년 이상 간격이 있으면 실패합니다.
elreimundo

2
나는 그 아이디어가 마음에 들지만 날짜 범위가 정말로 길어지면 잘못된 것입니다. 내 예 Date.new(2014, 10, 31), Date.new(1997, 4, 30)에서 210 개월 대신 213을 받았습니다. 그 이유 1.month.seconds는 한 달의 평균 초가 아니라 30 일의 초 수 이기 때문 입니다. 다른 사람들이 버그가없는 상태를 유지하도록 반대 투표.
Joe Eifert

1
이 실 거예요 작업을 30 일이 아닌 달을 선택하면
DIMA

2
이 방법은 그다지 정확하지 않습니다.
vagabond

9

질문을 "날짜의 시작일 사이에 첫 번째 날이 몇 일인지"로 바꾸고 함수 스타일 데이터 변환을 사용할 수 있습니다.

(date1.beginning_of_month...date2.beginning_of_month).select { |date| date.day == 1 }.size

그리고 원래의 질문으로 돌아가려면 일을 더하고 (첫 번째 질문과 마찬가지로) 합계의 평균을 구할 수 있습니다.
Joe Eifert

9

둘 다 날짜라고 가정하면 ((date2 - date1).to_f / 365 * 12).round 간단합니다.


아주 좋은 해결책! 깨끗하고 단순하며 수년에 걸쳐 작동합니다. 즉, 2018 년 2 월과 2017 년 12 월 사이의 개월 범위
jeffdill2

1
시간, 분, 초를 고려해야 함 ((date2 - date1).to_f / 60 / 60 / 24 / 365 * 12).round
scarver2

1
@ scarver2 계산에서 얻은 숫자는 완전히 다릅니다. 우리가하고있는 일은 일을 몇 달로 바꾸는 것뿐입니다. 이것은 한 달에 30.4167 일을 가정하기 때문에 매우 정확하지는 않지만 매우 가깝고 어쨌든 반올림합니다.
Andreykul

3
start_date = Date.today
end_date   = Date.today+90
months = (end_date.month+end_date.year*12) - (start_date.month+start_date.year*12)

//months = 3

2

내가 찾은 또 다른 솔루션 (이미 여기에 게시 된 솔루션으로 구축 됨)은 결과에 한 달의 분수를 포함하려는 경우입니다. 예를 들어 거리는입니다 1.2 months.

((date2.to_time - date1.to_time)/1.month.second).round(1) #Tenth of a month Ex: 1.2
((date2.to_time - date1.to_time)/1.month.second).round(2) #Hundreth, ex: 1.23 months
etc...

1
당신이 whish에서만 개월이 실제로 경과 표시하는 경우 바닥 raplacing 라운드를 시도
마티아스

2
def difference_in_months(date1, date2)
  month_count = (date2.year == date1.year) ? (date2.month - date1.month) : (12 - date1.month + date2.month)
  month_count = (date2.year == date1.year) ? (month_count + 1) : (((date2.year - date1.year - 1 ) * 12) + (month_count + 1))
  month_count
end

1
이것에 대해 자세히 설명해 주시면 유용할까요? 일반적으로 SO 답변에는 코드의 기능과 솔루션으로 작동하는 이유에 대한 설명이 포함되어 있습니다.
Single Entity

1

두 날짜 사이에 정확한 개월 수 (소수점 포함)가 필요했고 다음과 같은 방법을 작성했습니다.

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

BTW는 레일 'ActiveSupport에 의존
mtrolle

1

다음은 무차별 대입 변형입니다.

date1 = '2016-01-05'.to_date
date2 = '2017-02-27'.to_date
months = 0

months += 1 while (date2 << (count+1)) >= date1
puts months # => 13

date2 항상보다 커야합니다. date1


0

여기 또 다른 방법이 있습니다. 이것은 두 날짜 사이의 전체 개월 수를 계산하는 데 도움이됩니다.

def months_difference(date_time_start, date_time_end)
  curr_months = 0
  while (date_time_start + curr_months.months) < date_time_end
    curr_months += 1
  end
  curr_months -= 1 if (date_time_start + curr_months.months) > date_time_end
  curr_months.negative? ? 0 : curr_months
end

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