73 Stimmen

Wie rundet man in Ruby eine Zeit auf die nächsten 15 Minuten ab?

Gibt es eine einfache Möglichkeit, eine Zeit auf die nächsten 15 Minuten abzurunden?

Das ist es, was ich derzeit tue. Gibt es einen einfacheren Weg, dies zu tun?

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

138voto

Ryan McGeary Punkte 228632

Sie sagten "abrunden", also bin ich mir nicht sicher, ob Sie tatsächlich nach der Runde oder dem Boden suchen, aber hier ist der Code, um beides zu tun. Ich denke, so etwas liest sich sehr gut, wenn Sie Folgendes hinzufügen round_off y floor Methoden für die Klasse Time. Der zusätzliche Vorteil ist, dass Sie leichter durch eine beliebige Zeitteilung runden können.

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).utc
  end

  def floor(seconds = 60)
    Time.at((self.to_f / seconds).floor * seconds).utc
  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

Note : ActiveSupport war nur für die hübschen 15.minutes Argument. Wenn Sie diese Abhängigkeit nicht wünschen, verwenden Sie 15 * 60 stattdessen.

23voto

cmsjr Punkte 52971

Ich bin nicht sehr vertraut mit der Syntax von Ruby, aber Sie können runden unten auf die nächsten 15 Minuten mit Hilfe von modulo. (d. h. x - (x modulo 15)). Ich würde vermuten, dass die Syntax in etwa wie folgt aussehen würde

t.min - ( t.min % 15)

Damit stehen Ihnen die Werte 0, 15, 30 und 45 zur Verfügung. Angenommen 0 <= t.min <= 59.

22voto

Jarno Lamberg Punkte 930

Ich dachte, ich würde eine andere Lösung posten, die das Auf- und Abrunden auf die nächste angegebene Anzahl von Sekunden ermöglicht. Oh, und dies nicht ändern, die Zeitzone wie einige der anderen Lösungen.

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 wurde in den Beispielen für die Funktion x.minutes verwendet. Sie können stattdessen 15 * 60 verwenden.

Die Methoden Boden und Decke können auf der Grundlage dieser Lösung leicht umgesetzt werden.

19voto

jewilmeer Punkte 1866

Ich habe eine sehr lesenswerte Lösung gefunden;

Dadurch wird Ihre Zeit auf die letzten gerundeten 15 Minuten aufgerundet. Sie können die 15.minutes auf jede mögliche Zeitspanne.

Time.at(Time.now.to_i - (Time.now.to_i % 15.minutes))

17voto

Brian Hempel Punkte 8474

Ich habe die Abgerundeter Edelstein um diese Art von Fällen zu bearbeiten.

Das Abrunden einer Zeit wird so einfach wie der Aufruf floor_to über die Uhrzeit. Auf- und Abrunden werden ebenfalls unterstützt ( ceil_to y round_to ).

require "rounding"

Time.current.floor_to(15.minutes) # => Thu, 07 May 2015 16:45:00 UTC +00:00
Time.current.ceil_to(15.minutes)  # => Thu, 07 May 2015 17:00:00 UTC +00:00
Time.current.round_to(15.minutes) # => Thu, 07 May 2015 16:45:00 UTC +00:00

Die Zeitzone der ursprünglichen Zeit bleibt erhalten (in diesem Fall UTC). Sie brauchen ActiveSupport nicht zu laden - Sie können schreiben floor_to(15*60) und es wird gut funktionieren. Der Edelstein verwendet Rationale Zahlen, um Rundungsfehler zu vermeiden. Sie können auf den nächsten Montag aufrunden, indem Sie einen Offset angeben round_to(1.week, Time.parse("2015-5-4 00:00:00 UTC")) . Wir verwenden es in der Produktion.

Ich schrieb eine Blogbeitrag die mehr erklärt. Ich hoffe, Sie finden es hilfreich.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X