Gibt es eine einfache Funktion zum Abrunden UP eine DateTime
auf die nächsten 15 Minuten?
Z.B
2011-08-11 16:59
wird 2011-08-11 17:00
2011-08-11 17:00
bleibt als 2011-08-11 17:00
2011-08-11 17:01
wird 2011-08-11 17:15
DateTime RoundUp(DateTime dt, TimeSpan d)
{
return new DateTime((dt.Ticks + d.Ticks - 1) / d.Ticks * d.Ticks, dt.Kind);
}
Beispiel:
var dt1 = RoundUp(DateTime.Parse("2011-08-11 16:59"), TimeSpan.FromMinutes(15));
// dt1 == {11/08/2011 17:00:00}
var dt2 = RoundUp(DateTime.Parse("2011-08-11 17:00"), TimeSpan.FromMinutes(15));
// dt2 == {11/08/2011 17:00:00}
var dt3 = RoundUp(DateTime.Parse("2011-08-11 17:01"), TimeSpan.FromMinutes(15));
// dt3 == {11/08/2011 17:15:00}
DateTime RoundUp(DateTime dt, TimeSpan d) { return new DateTime(((dt.Ticks + d.Ticks - 1) / d.Ticks) * d.Ticks, dt.Kind); }
Es wurde eine Lösung gefunden, bei der Zahlen nicht multipliziert und geteilt
long
werden.Verwendung:
quelle
%d.Ticks
inRoundUp
notwendig?d.Ticks - (dt.Ticks % d.Ticks))
wird notwendigerweise kleiner sein alsd.Ticks
, also sollte die Antwort gleich richtig sein?Wenn Sie auf das nächste Zeitintervall runden müssen (nicht aufwärts), empfehle ich Folgendes
quelle
Ergebnisse:
quelle
2011-08-11 17:00:01
wird abgeschnitten auf2011-08-11 17:00:00
Da ich es hasse, das Rad neu zu erfinden, würde ich wahrscheinlich diesem Algorithmus folgen, um einen DateTime-Wert auf ein bestimmtes Zeitinkrement (Zeitspanne) zu runden:
DateTime
zu rundenden Wert in einen dezimalen Gleitkommawert, der die gesamte und gebrochene Anzahl vonTimeSpan
Einheiten darstellt.Math.Round()
.TimeSpan
Einheit multiplizieren .DateTime
Wert aus der gerundeten Anzahl von Ticks und geben Sie ihn an den Anrufer zurück.Hier ist der Code:
quelle
DateTime
, aber ich mag auch die Möglichkeit, rund um bis zu einem Vielfachenunit
. Das WeitergebenMidpointRounding.AwayFromZero
anRound
hat nicht den gewünschten Effekt. Haben Sie etwas anderes im Sinn, indem Sie einMidpointRounding
Argument akzeptieren ?Meine Version
Als Methode würde es so sperren
und heißt so
quelle
Elegant?
quelle
Achtung: Die obige Formel ist falsch, dh die folgende:
sollte umgeschrieben werden als:
quelle
/ d.Ticks
auf das nächste 15-Minuten-Intervall abgerundet wird (nennen wir diese "Blöcke"), garantiert das Hinzufügen nur eines halben Blocks keine Aufrundung. Überlegen Sie, wann Sie 4,25 Blöcke haben. Wenn Sie 0,5 Blöcke hinzufügen, testen Sie, wie viele Ganzzahlblöcke Sie haben. Sie haben immer noch nur 4. Das Hinzufügen eines Ticks weniger als ein vollständiger Block ist die richtige Aktion. Es stellt sicher, dass Sie immer zum nächsten Blockbereich aufsteigen (bevor Sie abrunden), verhindert jedoch, dass Sie zwischen exakten Blöcken wechseln. (IE, wenn Sie einen vollständigen Block zu 4.0 Blöcken hinzugefügt haben, würde 5.0 auf 5 runden, wenn Sie 4 möchten. 4.99 wird 4. sein)Eine ausführlichere Lösung, die Modulo verwendet und unnötige Berechnungen vermeidet.
quelle
Dies ist eine einfache Lösung, um auf die nächste Minute aufzurunden. Die TimeZone- und Kind-Informationen der DateTime bleiben erhalten. Es kann weiter an Ihre eigenen Bedürfnisse angepasst werden (wenn Sie auf die nächsten 5 Minuten runden müssen usw.).
quelle
Sie können diese Methode verwenden. Sie verwendet das angegebene Datum, um sicherzustellen, dass die zuvor im Datum / Uhrzeit-Objekt angegebenen Globalisierungs- und Datums- / Uhrzeitarten beibehalten werden.
.Net Fiddle Test
Wenn Sie die Zeitspanne zum Runden verwenden möchten, können Sie diese verwenden.
TimeSpan Geige
quelle
var d = new DateTime(2019, 04, 15, 9, 40, 0, 0);
// sollte 9:42 sein, aber keine dieser Methoden funktioniert so?