Existe uma função simples para arredondamento UP um DateTime
dos mais próximos 15 minutos?
Por exemplo
2011-08-11 16:59
torna-se 2011-08-11 17:00
2011-08-11 17:00
permanece como 2011-08-11 17:00
2011-08-11 17:01
torna-se 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);
}
Exemplo:
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); }
Surgiu uma solução que não envolve multiplicar e dividir
long
números.Uso:
fonte
%d.Ticks
naRoundUp
necessário?d.Ticks - (dt.Ticks % d.Ticks))
será necessariamente menor qued.Ticks
, então a resposta deve ser a mesma correta?se você precisar arredondar para um intervalo de tempo mais próximo (não acima), sugiro usar o seguinte
fonte
Resultados:
fonte
2011-08-11 17:00:01
fica truncado para2011-08-11 17:00:00
Como odeio reinventar a roda, provavelmente seguiria esse algoritmo para arredondar um valor DateTime para um incremento especificado de tempo (Timespan):
DateTime
valor a ser arredondado em um valor decimal de ponto flutuante representando o número inteiro e fracionário deTimeSpan
unidades.Math.Round()
.TimeSpan
unidade.DateTime
valor a partir do número arredondado de ticks e devolva-o ao chamador.Aqui está o código:
fonte
DateTime
, mas também quero a capacidade de rodada -se a um múltiplo deunit
. PassarMidpointRounding.AwayFromZero
paraRound
não tem o efeito desejado. Você tem outra coisa em mente ao aceitar umMidpointRounding
argumento?Minha versão
Como método, ele trava assim
e é chamado assim
fonte
Elegante?
fonte
Cuidado: a fórmula acima está incorreta, ou seja, o seguinte:
deve ser reescrito como:
fonte
/ d.Ticks
arredondada para o intervalo de 15 minutos mais próximo (vamos chamar esses "blocos"), adicionar apenas meio bloco não garante o arredondamento. Considere quando você tiver 4,25 blocos. Se você adicionar 0,5 blocos e testar quantos blocos inteiros você possui, você ainda terá apenas 4. Adicionar uma marca a menos que um bloco completo é a ação correta. Ele garante que você sempre avance para o próximo intervalo de blocos (antes de arredondar para baixo), mas impede que você se mova entre os blocos exatos. (IE, se você adicionou um bloco inteiro para 4,0 blocos, 5.0 seria arredondar para 5, quando quiser 4. 4.99 será 4.)Uma solução mais detalhada, que utiliza módulo e evita cálculos desnecessários.
fonte
Esta é uma solução simples para arredondar para o minuto mais próximo. Ele preserva as informações TimeZone e Kind do DateTime. Ele pode ser modificado para atender às suas próprias necessidades (se você precisar arredondar para os 5 minutos mais próximos, etc.).
fonte
Você pode usar esse método, ele usa a data especificada para garantir a manutenção de qualquer tipo de globalização e data e hora especificado anteriormente no objeto data e hora.
Teste de violino líquido
Se você quiser usar o TimeSpan para arredondar, poderá usá-lo.
TimeSpan Fiddle
fonte
var d = new DateTime(2019, 04, 15, 9, 40, 0, 0);
// deve ser 9:42, mas nenhum desses métodos funciona assim?