2 votes

Comment calculer le prochain jour anniversaire mensuel

Si j'ai un processus que je voudrais exécuter un jour spécifique du mois. Quelle est la meilleure façon de calculer cet anniversaire chaque mois ? Par exemple, si je veux facturer quelqu'un le 30 de chaque mois.

Je sais qu'il y a des GEMs que je peux installer, mais ça semble exagéré. De plus, le Date#>> ne fonctionnera que pour le calcul du mois suivant. Qu'en est-il du mois suivant ?

J'ai posté mon code ci-dessous qui est la meilleure solution que j'ai trouvée.

1voto

Stefan Points 23363

D'après votre propre réponse, cela pourrait également fonctionner :

def next_month_anniversary(mday, today = Date.today)
  d = today.next_month
  if Date.valid_date?(d.year, d.month, mday)
    Date.new(d.year, d.month, mday)
  else
    Date.new(d.year, d.month, -1)
  end
end

ou un peu plus condensé :

def next_month_anniversary(mday, today = Date.today)
  d = today.next_month
  mday = -1 unless Date.valid_date?(d.year, d.month, mday)
  Date.new(d.year, d.month, mday)
end

Exemple :

next_month_anniversary(30, Date.new(2018, 1, 31))
#=> #<Date: 2018-02-28 ...>

1voto

s1mpl3 Points 1241

Vous devez utiliser l'avance

https://apidock.com/rails/DateTime/advance

Date.current.advance(months: 2)   

Modifier par commentaire : Appeler à l'avance à votre date initiale connaître tout événement futur

 my_date = Date.new(2018, 1, 30) #example but mean to be the date you set up as to be recurrent
 my_date.advance(months:1) #Wed, 28 Feb 2018

0voto

Tom Rossi Points 1525

C'est la meilleure solution que j'ai pu trouver. Dans ce scénario, nous sommes le 31 janvier et je voudrais renvoyer un anniversaire le 30 de chaque mois.

> MyClass.next_month_anniversary(30, '2018-01-30'.to_date)
 => Wed, 28 Feb 2018    

Voici le code :

  def next_month_anniversary(day_of_month, today = Date.today)
    month = (today >> 1).month
    year =  (today >> 1).year
    days_in_month = Time.days_in_month(month.to_i, year.to_i)
    if days_in_month < day_of_month
      day = days_in_month
    else
      day = day_of_month
    end
    Date.new(year.to_i, month.to_i, day.to_i)
  end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X