Czy istnieje prosty funkcja zaokrąglania UPDateTime
do najbliższych 15 minut?
Na przykład
2011-08-11 16:59
staje się 2011-08-11 17:00
2011-08-11 17:00
pozostaje jako 2011-08-11 17:00
2011-08-11 17:01
staje się 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);
}
Przykład:
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); }
Pojawiło się rozwiązanie, które nie wymaga mnożenia i dzielenia
long
liczb.Stosowanie:
źródło
%d.Ticks
wRoundUp
niezbędne?d.Ticks - (dt.Ticks % d.Ticks))
będzie koniecznie mniejsze niżd.Ticks
, więc odpowiedź powinna być taka sama, poprawna?jeśli chcesz zaokrąglić do najbliższego przedziału czasu (nie w górę), sugeruję użycie poniższego
źródło
Wyniki:
źródło
2011-08-11 17:00:01
zostaje obcięty do2011-08-11 17:00:00
Ponieważ nienawidzę odkrywać koła na nowo, prawdopodobnie zastosowałbym ten algorytm, aby zaokrąglić wartość DateTime do określonego przyrostu czasu (Timespan):
DateTime
wartość, która ma być zaokrąglona, na dziesiętną wartość zmiennoprzecinkową reprezentującą całkowitą i ułamkową liczbęTimeSpan
jednostek.Math.Round()
.TimeSpan
jednostce.DateTime
wartości z zaokrąglonej liczby taktów i zwróć ją do dzwoniącego.Oto kod:
źródło
DateTime
, ale chcę też mieć możliwość zaokrąglania w górę do wielokrotnościunit
. PrzechodzenieMidpointRounding.AwayFromZero
doRound
nie daje pożądanego efektu. Czy przyjmującMidpointRounding
argument , masz na myśli coś innego ?Moja wersja
Jako metoda blokowałby się w ten sposób
i tak się nazywa
źródło
Elegancki?
źródło
Uwaga: powyższy wzór jest niepoprawny, czyli:
należy przepisać jako:
źródło
/ d.Ticks
zaokrąglane w dół do najbliższego 15-minutowego przedziału (nazwijmy te „bloki”), dodanie tylko połowy bloku nie gwarantuje zaokrąglenia w górę. Zastanów się, kiedy masz 4,25 bloków. Jeśli dodasz 0,5 bloku, a następnie sprawdź, ile masz bloków całkowitych, nadal masz tylko 4. Dodanie jednego ticka mniej niż pełny blok jest działaniem poprawnym. Zapewnia, że zawsze przechodzisz w górę do następnego zakresu bloków (przed zaokrągleniem w dół), ale zapobiega przechodzeniu między dokładnymi blokami. (IE, jeśli dodałeś pełny blok do 4.0 bloków, 5.0 zaokrągliłoby do 5, kiedy chcesz 4. 4.99 będzie 4.)Bardziej rozwlekłe rozwiązanie, które wykorzystuje modulo i pozwala uniknąć niepotrzebnych obliczeń.
źródło
Jest to proste rozwiązanie pozwalające zaokrąglić w górę do najbliższej 1 minuty. Zachowuje informacje TimeZone i Kind z DateTime. Można go dodatkowo zmodyfikować, aby dopasować go do własnych potrzeb (jeśli chcesz zaokrąglić do najbliższych 5 minut itp.).
źródło
Możesz użyć tej metody, używa ona określonej daty, aby upewnić się, że zachowuje wszystkie rodzaje globalizacji i daty / godziny określone wcześniej w obiekcie datetime.
.Net Fiddle Test
Jeśli chcesz użyć TimeSpan do zaokrąglenia, możesz użyć tego.
TimeSpan Fiddle
źródło
var d = new DateTime(2019, 04, 15, 9, 40, 0, 0);
// powinna wynosić 9:42, ale żadna z tych metod nie działa w ten sposób?