73 votes

Comment arrondir un temps aux 15 minutes les plus proches en Ruby?

Existe-t-il un moyen facile d’arrondir un temps aux 15 minutes les plus proches?

C'est ce que je suis en train de faire. Y a-t-il un moyen plus facile de le faire?

 t = Time.new
rounded_t = Time.local(t.year, t.month, t.day, t.hour, t.min/15*15)
 

138voto

Ryan McGeary Points 76053

Vous avez dit "ronde", donc je ne sais pas si vous êtes réellement à la recherche pour le tour ou le sol, mais voici le code pour faire les deux. Je pense que quelque chose comme ce lit très bien si vous ajoutez round_off et floor méthodes de la classe Temps. L'avantage est que vous pouvez plus facilement le tour par tout moment de la partition.

require 'active_support/core_ext/numeric' # from gem 'activesupport'

class Time
  # Time#round already exists with different meaning in Ruby 1.9
  def round_off(seconds = 60)
    Time.at((self.to_f / seconds).round * seconds)
  end

  def floor(seconds = 60)
    Time.at((self.to_f / seconds).floor * seconds)
  end
end

t = Time.now                    # => Thu Jan 15 21:26:36 -0500 2009
t.round_off(15.minutes)         # => Thu Jan 15 21:30:00 -0500 2009
t.floor(15.minutes)             # => Thu Jan 15 21:15:00 -0500 2009

Remarque: ActiveSupport était seulement nécessaire pour la jolie 15.minutes argument. Si vous ne voulez pas que la dépendance, utilisez 15 * 60 à la place.

23voto

cmsjr Points 16766

Je ne suis pas très familier avec la syntaxe de rubis mais vous pouvez arrondir les 15 minutes les plus proches en utilisant modulo. (ie x - (x modulo 15)). Je suppose que la syntaxe serait quelque chose comme

 t.min - ( t.min % 15)
 

Cela fera de votre ensemble de valeurs possibles 0, 15, 30 et 45. En supposant que 0 <= t.min <= 59.

22voto

Jarno Lamberg Points 301

Je pensais que je posterais une autre solution qui permet d'arrondir au plus proche nombre de secondes donné. Oh, et cela ne change pas le fuseau horaire comme certaines des solutions.

 class Time
  def round(sec=1)
    down = self - (self.to_i % sec)
    up = down + sec

    difference_down = self - down
    difference_up = up - self

    if (difference_down < difference_up)
      return down
    else
      return up
    end
  end
end

t = Time.now                             # => Mon Nov 15 10:18:29 +0200 2010
t.round(15.minutes)                      # => Mon Nov 15 10:15:00 +0200 2010
t.round(20.minutes)                      # => Mon Nov 15 10:20:00 +0200 2010
t.round(60.minutes)                      # => Mon Nov 15 10:00:00 +0200 2010
 

ActiveSupport a été utilisé dans les exemples pour la fonctionnalité x.minutes. Vous pouvez utiliser 15 * 60 à la place.

Les méthodes sol et plafond peuvent être facilement mises en œuvre sur la base de cette solution.

11voto

Chuck Points 138930

Depuis que Ruby autorise l’arithmétique (en secondes) sur Times, vous pouvez simplement faire ceci:

 t = Time.new
rounded_t = t-t.sec-t.min%15*60
 

6voto

Shalmanese Points 2518

Vous pourriez faire:

 Time.at(t.to_i/(15*60)*(15*60))
 

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