6
votes

Rails 4: Comment ajouter / soustraire des multiples de quartiers à ce jour?

Pour obtenir les dates de début et de fin du trimestre en cours pourrait faire: XXX PRE>

Pour obtenir les dates du trimestre précédent, cela semble être une approche raisonnable: p>

def quarter_dates(quarter_offset)
  # --------------------------------------------  
  #    quarter_offset        return value
  # --------------------------------------------
  #          0           current quarter dates
  #          1             prev quarter dates
  #          2         before prev quarter dates
  #         ...                   ...

  # Implementation goes here...

  [start_of_quarter, end_of_quarter]
end


0 commentaires

8 Réponses :


0
votes
quarter_dates   => [Tue, 01 Apr 2014, Mon, 30 Jun 2014]
quarter_dates 1 => [Wed, 01 Jan 2014, Mon, 31 Mar 2014]
quarter_dates 9 => [Sun, 01 Jan 2012, Sat, 31 Mar 2012]

0 commentaires

0
votes

Je pense que la réponse est de travailler dans des numéros de mois et d'éviter d'utiliser des mois de rubis. Ceci est laid, mais je pense que cela fonctionne

def quarter_dates(quarter_offset = 0)
  time = Time.now
  current_quarter = (time.month - 1) / 3
  normalised_offset = current_quarter - quarter_offset
  offset_quarter = normalised_offset % 4
  year_offset = normalised_offset / 4
  offset_year = time.year + year_offset
  quarter_start_month = 3 * (offset_quarter) + 1
  next_quarter_start_month = quarter_start_month + 3
  quarter_start = Time.local(offset_year, quarter_start_month, 1)
  if next_quarter_start_month == 13
    quarter_end = Time.local((offset_year + 1), 1, 1) - 1
  else
    quarter_end = Time.local(offset_year, next_quarter_start_month, 1) - 1
  end
  [quarter_start, quarter_end]
end


0 commentaires

2
votes

Utilisation des rails Ma solution est

def quarter_dates(quarter_offset = 0)
  quarter_start = Time.now.to_date.beginning_of_quarter - (3 * quarter_offset).months
  quarter_end = quarter_start.end_of_quarter
  [quarter_start,quarter_end]
end


3 commentaires

3 mois n'est pas toujours 1 quart d'année.


@Johnc, fournissez un exemple, s'il vous plaît


Désolé, votre fonction fonctionne bien. Si vous faites une modification rapide, je vais supprimer ma voix basse.



6
votes

Je le ferais de cette façon:

def quarter_dates(offset)
  date = Date.today << (offset * 3)
  [date.beginning_of_quarter, date.end_of_quarter]
end

puts quarter_dates(0) #=> [Tue, 01 Apr 2014, Mon, 30 Jun 2014]
puts quarter_dates(1) #=> [Wed, 01 Jan 2014, Mon, 31 Mar 2014]
puts quarter_dates(9) #=> [Sun, 01 Jan 2012, Sat, 31 Mar 2012]


3 commentaires

@spickermann: Votre solution suppose que 1 mois est toujours de 30 jours. Supposons que date.today = date.new (2014, 9, 30) et offset = 1 . Vous obtiendrez date.beginning_of_quarter = 1 avril 2014 qui est le début du trimestre en cours, pas le précédent!


@ Mishamoroshko: Je suis désolé, mais je pense que tu as tort. '2014-09-30' est le dernier jour du troisième trimestre. Par conséquent, le trimestre précédent est le deuxième trimestre. Le début du deuxième trimestre est «2014-04-01» (et ses fins de «2014-06-30»). Exactement ce que ma méthode revient. En outre, <<< / code> est une méthode rubis qui ne suppose pas 30 jours ou similaire. Veuillez prendre votre temps pour revoir votre commentaire.


@spickermann: Je suis désolé, mais je pense que tu as raison !! Solution très élégante. Merci beaucoup!



2
votes

Je suppose des compensations positives pour les décalages futurs et négatifs du passé. Vous pouvez faire des compensations négatives pour les décalages futurs et positifs du passé en remplaçant mois_since avec mois_ago .

Vous pouvez également éventuellement passer une journée si vous souhaitez obtenir des quartiers relatifs à elle. xxx

test: xxx


7 commentaires

Cela échoue pour le 1er janvier et 30 septembre


@Johnc Il n'y a pas de quart qui commence avec le 1er janvier et se termine avec le 30 septembre. Je pense que vous entendez le troisième quart qui commence avec JUL 1 (sixième mois) et se termine avec le 30 septembre (dernier jour du neuvième mois) qui fonctionne parfaitement pour moi. Qu'est-ce que ça te donne?


Je veux dire définir votre rendez-vous au 1er janvier et soustrayez un quart. Même pour le 30 septembre. Dans ma solution, j'ai posté une suite de test RSPEC qui le fera pour vous. S'il vous plaît n'hésitez pas à l'essayer.


@Johnc C'est vrai, j'ai juste oublié de retourner entre les deux manières possibles. C'est corrigé maintenant, merci :)


Désolé, ma spécification ne fonctionne pas pour votre fonction car elle ne supporte pas la date .Today


@JOHNC Vous pouvez l'essayer dans la console Rails Homme, I Poche-Is N'ayez pas toujours l'unité Testez tout.


Essayez: date.stub (: aujourd'hui) {date.new (2013,1,1)} ?



0
votes

Je serais tenté de généraliser la formule que vous avez utilisée dans votre question. Les compensations négatives représentent des quartiers futurs, des compensations positives passées par les quartiers.

def quarter_dates(quarter_offset = 0)
  reference_date = Time.now.to_date
  until quarter_offset == 0
    if quarter_offset > 0
      reference_date = reference_date.beginning_of_quarter - 1
      quarter_offset -= 1
    else 
      reference_date = reference_date.end_of_quarter + 1
      quarter_offset += 1
    end
  end
  [reference_date.beginning_of_quarter, reference_date.end_of_quarter]
end


2 commentaires

Vous avez une faute de frappe à la fin, date de référence doit être référence_date . J'ai essayé de modifier, mais apparemment modifications doit avoir 6 caractères de longueur. : /


Merci @RubeonRails bien repéré. :) Typo Fixe.



0
votes

Je sais que ce fil est vieux, mais j'ai couru dans le même problème ... Cette solution a fonctionné pour moi:

beginning_of_next_quarter=Date.today.beginning_of_quarter + 3.month
end_of_next_quarter=Date.today.end_of_quarter + 3.month


0 commentaires

1
votes

Ajouter un .QuRarter Méthode d'initialisation à Entier .

Dans notre cas, nous étions juste intéressés à pouvoir ajouter un trimestre à une date / code> ou temps aussi facilement que nous le faisons avec un mois. Nous avons donc ajouté une initialiseur qui ajoute la méthode à la classe entier Classe:

config / initialiseurs / trimestre.rb xxx

alors vous pouvez facilement l'appeler comme si vous le faites avec .days , .months xxx

Si vous recherchez le début et la fin d'un quart, vous pouvez le combiner avec dound_of_quarter et end_of_quarter pour passer facilement à un quart et obtenez vos dates de début et de fin.


0 commentaires