Ich habe zwei Ruby on Rails DateTime-Objekte. Wie finde ich die Anzahl der Monate zwischen ihnen? (Denken Sie daran, dass sie zu verschiedenen Jahren gehören könnten)
Ich habe zwei Ruby on Rails DateTime-Objekte. Wie finde ich die Anzahl der Monate zwischen ihnen? (Denken Sie daran, dass sie zu verschiedenen Jahren gehören könnten)
Antworten:
(date2.year * 12 + date2.month) - (date1.year * 12 + date1.month)
Weitere Informationen unter http://www.ruby-forum.com/topic/72120
(12 * (date2.year - date1.year) + date2.month - date1.month).abs if date1 && date2
Eine genauere Antwort würde Tage in der Ferne berücksichtigen.
Zum Beispiel, wenn Sie , dass der Monat Abstand betrachten aus 28/4/2000
und 1/5/2000
ist 0
nicht 1
, dann können Sie:
(date2.year - date1.year) * 12 + date2.month - date1.month - (date2.day >= date1.day ? 0 : 1)
Probieren Sie es aus
((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
(Ich gebe die Formatierung auf ... kann es nicht herausfinden)
Date.new(2014, 10, 31), Date.new(1997, 4, 30)
erhielt ich 213 statt 210 Monate. Der Grund dafür ist, dass 1.month.seconds
die Anzahl der Sekunden in 30 Tagen und nicht die durchschnittlichen Sekunden in einem Monat sind. Downvoting, damit andere fehlerfrei bleiben.
Sie können die Frage wie folgt umformulieren: "Wie viele erste Tage liegen zwischen den Anfängen der Monate der Daten?" Und dann Datentransformationen im funktionalen Stil verwenden:
(date1.beginning_of_month...date2.beginning_of_month).select { |date| date.day == 1 }.size
Angenommen, beide sind Daten:
((date2 - date1).to_f / 365 * 12).round
einfach.
((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
Eine andere Lösung, die ich gefunden habe (basierend auf einer hier bereits veröffentlichten Lösung), ist für den Fall, dass das Ergebnis Bruchteile eines Monats enthalten soll. Zum Beispiel ist die Entfernung 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
Ich brauchte die genaue Anzahl von Monaten (einschließlich Dezimalstellen) zwischen zwei Daten und schrieb die folgende Methode dafür.
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
Wenn wir den 26. September mit dem 26. September (am selben Tag) vergleichen, berechne ich ihn als 1 Tag. Wenn Sie das nicht benötigen, können Sie die erste Zeile in der Methode entfernen:period_end = period_end + 1.day
Es besteht die folgenden Spezifikationen:
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
Hier ist eine andere Methode. Dies hilft bei der Berechnung der Anzahl ganzer Monate zwischen zwei Daten
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