J'ai deux Ruby on Rails DateTime objets. Comment trouver le nombre de mois entre eux? (Gardant à l'esprit qu'ils peuvent appartenir à des années différentes))
(date2.year * 12 + date2.month) - (date1.year * 12 + date1.month)
plus d'informations sur http://www.Ruby-forum.com/topic/7212
Une réponse plus précise prendrait en compte les jours de distance.
Par exemple, si vous considérez que la distance mensuelle de 28/4/2000
et 1/5/2000
est 0
plutôt que 1
, vous pouvez alors utiliser:
(date2.year - date1.year) * 12 + date2.month - date1.month - (date2.day >= date1.day ? 0 : 1)
Essayez
((date2.to_time - date1.to_time)/1.month.second).to_i
Vous pouvez reformuler la question comme "combien de 1er jours existe-t-il entre le début des mois des dates", puis utiliser des transformations de données de style fonctionnel:
(date1.beginning_of_month...date2.beginning_of_month).select { |date| date.day == 1 }.size
En supposant que les deux sont des dates: ((date2 - date1).to_f / 365 * 12).round
simple.
Une autre solution que j'ai trouvée (basée sur une solution déjà publiée ici) est pour si vous voulez que le résultat comprenne des fractions de mois. Par exemple, la distance est 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
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
Voici une variante de forçage brutal:
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
doit toujours être supérieur à date1
Voici une autre méthode. Cela vous aidera à calculer le nombre de mois entiers entre deux dates
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
J'avais besoin du nombre exact de mois (décimales comprises) entre deux dates et j'ai écrit la méthode suivante pour cela.
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
Si l'on compare, disons du 26 septembre au 26 septembre (même jour), je le calcule comme 1 jour. Si vous n'en avez pas besoin, vous pouvez supprimer la première ligne de la méthode: period_end = period_end + 1.day
Il passe les spécifications suivantes:
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