¿Hay una simple función para redondear UP una DateTime
a los 15 minutos más cercanos?
P.ej
2011-08-11 16:59
se convierte 2011-08-11 17:00
2011-08-11 17:00
se queda como 2011-08-11 17:00
2011-08-11 17:01
se convierte 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);
}
Ejemplo:
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); }
Se le ocurrió una solución que no implica multiplicar y dividir
long
números.Uso:
fuente
%d.Ticks
enRoundUp
necesario?d.Ticks - (dt.Ticks % d.Ticks))
será necesariamente menor qued.Ticks
, por lo que la respuesta debería ser la misma correcta?si necesita redondear al intervalo de tiempo más cercano (no hacia arriba), le sugiero que use lo siguiente
fuente
Resultados:
fuente
2011-08-11 17:00:01
se trunca a2011-08-11 17:00:00
Como odio reinventar la rueda, probablemente seguiría este algoritmo para redondear un valor DateTime a un incremento de tiempo especificado (Timespan):
DateTime
valor que se redondeará en un valor decimal de coma flotante que represente el número total y fraccionario deTimeSpan
unidades.Math.Round()
.TimeSpan
unidad.DateTime
valor del número redondeado de ticks y devuélvelo a la persona que llama.Aquí está el código:
fuente
DateTime
, pero también quiero la capacidad de ronda hasta a un múltiplo deunit
. PasarMidpointRounding.AwayFromZero
aRound
no tiene el efecto deseado. ¿Tienes algo más en mente al aceptar unaMidpointRounding
discusión?Mi version
Como método se bloquearía así
y se llama así
fuente
¿Elegante?
fuente
Precaución: la fórmula anterior es incorrecta, es decir, la siguiente:
debe reescribirse como:
fuente
/ d.Ticks
redondea al intervalo de 15 minutos más cercano (llamemos a estos "bloques"), agregar solo medio bloque no garantiza el redondeo. Considera cuando tienes 4.25 bloques. Si agrega 0.5 bloques, luego pruebe cuántos bloques enteros tiene, todavía tiene 4. Agregar una marca menos que un bloque completo es la acción correcta. Asegura que siempre te muevas al siguiente rango de bloque (antes de redondear hacia abajo), pero evita que te muevas entre bloques exactos. (IE, si agregaste un bloque completo a 4.0 bloques, 5.0 se redondearía a 5, cuando quieras 4. 4.99 será 4.)Una solución más detallada, que utiliza módulo y evita cálculos innecesarios.
fuente
Esta es una solución simple para redondear al minuto más cercano. Conserva la información de TimeZone y Kind de DateTime. Se puede modificar para adaptarse a sus propias necesidades (si necesita redondear a los 5 minutos más cercanos, etc.).
fuente
Puede usar este método, usa la fecha especificada para garantizar que mantenga el tipo de globalización y fecha y hora especificado previamente en el objeto de fecha y hora.
Prueba de violín .Net
Si desea usar el TimeSpan para redondear, puede usar esto.
TimeSpan Fiddle
fuente
var d = new DateTime(2019, 04, 15, 9, 40, 0, 0);
// debería ser 9:42 pero ninguno de estos métodos funciona así?