Tôi có hai đối tượng DateTime Ruby on Rails. Làm thế nào để tìm số tháng giữa chúng? (Hãy nhớ rằng họ có thể thuộc các năm khác nhau)
Tôi có hai đối tượng DateTime Ruby on Rails. Làm thế nào để tìm số tháng giữa chúng? (Hãy nhớ rằng họ có thể thuộc các năm khác nhau)
Câu trả lời:
(date2.year * 12 + date2.month) - (date1.year * 12 + date1.month)
thêm thông tin tại http://www.ruby-forum.com/topic/72120
(12 * (date2.year - date1.year) + date2.month - date1.month).abs if date1 && date2
Một câu trả lời chính xác hơn sẽ xem xét các ngày ở xa.
Ví dụ, nếu bạn xem xét rằng tháng khoảng cách từ 28/4/2000
và 1/5/2000
là 0
hơn 1
, sau đó bạn có thể sử dụng:
(date2.year - date1.year) * 12 + date2.month - date1.month - (date2.day >= date1.day ? 0 : 1)
Hãy thử
((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
(Tôi bỏ về định dạng ... không thể tìm nó ra)
Date.new(2014, 10, 31), Date.new(1997, 4, 30)
tôi, tôi nhận được 213 thay vì 210 tháng. Lý do 1.month.seconds
là số giây trong 30 ngày chứ không phải số giây trung bình trong một tháng. Từ chối để những người khác không có lỗi.
Bạn có thể diễn đạt lại câu hỏi là "có bao nhiêu ngày đầu tiên trong khoảng thời gian từ đầu tháng của các ngày", rồi sử dụng các phép biến đổi dữ liệu kiểu chức năng:
(date1.beginning_of_month...date2.beginning_of_month).select { |date| date.day == 1 }.size
Giả sử cả hai đều là ngày tháng:
((date2 - date1).to_f / 365 * 12).round
đơn giản.
((date2 - date1).to_f / 60 / 60 / 24 / 365 * 12).round
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
Một giải pháp khác mà tôi đã tìm thấy (được xây dựng dựa trên một giải pháp đã đăng ở đây) là nếu bạn muốn kết quả bao gồm các phần nhỏ của một tháng. Ví dụ khoảng cách là 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...
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
Tôi cần số tháng chính xác (bao gồm cả số thập phân) giữa hai ngày và đã viết phương pháp sau cho nó.
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
Nếu so sánh, giả sử ngày 26 tháng 9 với ngày 26 tháng 9 (cùng ngày), tôi tính nó là 1 ngày. Nếu bạn không cần, bạn có thể xóa dòng đầu tiên trong phương thức:period_end = period_end + 1.day
Nó vượt qua các thông số kỹ thuật sau:
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
Đây là một phương pháp khác. Điều này sẽ giúp tính toán số tháng nguyên giữa hai ngày
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