CTimeSpan.GetDays () e horário de verão
Pergunta
Eu encontrei em um bug em um programa C ++ MFC idade temos que calcula uma compensação (em dias) para uma determinada data a partir de uma data fixa para. Estávamos vendo resultados que estavam fora por um, por algum motivo, e eu segui-lo para onde o programador original tinha usado os CTimeSpan.GetDays () método. De acordo com a documentação :
Note que o horário de verão pode causar GetDays para retornar um resultado potencialmente surpreendente. Por exemplo, quando o DST é, com efeito, GetDays indica o número de dias entre 1 de Abril e 01 de maio como 29, não 30, porque um dia de Abril é encurtado por uma hora e, por conseguinte, não é considerado um dia completo.
Meu correção proposta é usar (obj.GetTotalHours()+1)/24
vez. Eu acho que cobriria todas as questões uma vez que este é um trabalho em lotes que é executado em aproximadamente o mesmo tempo todos os dias, mas eu pensei que eu ia perguntar as pessoas inteligentes aqui antes de implementá-lo se pode haver uma maneira melhor.
Esta é apenas uma questão de lado, mas eu também estou curioso como isso seria tratado se o programa pode ser executado a qualquer momento.
Solução
Seu correção funciona bem para obter o número de períodos inteiros de 24 horas entre duas vezes - desde que os eventos ocorrem ao mesmo tempo cada dia. Caso contrário, que "+1" na expressão poderia levar a um erro off-por-um.
Às vezes você não se importa que hora do dia em que o evento ocorreu, você só quero saber que dia. Nesse caso, é preciso zerar as horas, minutos e segundos, em seguida, usar a fórmula:
CTime startDay(start.GetYear(), start.GetMonth(), start.GetDay(), 0, 0, 0);
CTime finishDay(finish.GetYear(), finish.GetMonth(), finish.GetDay(), 0, 0, 0);
int days = ((finishDay - startDay).GetTotalHours() + 1) / 24;
Outras dicas
Uma pequena alteração ao que Mark sugeriu e ele funciona sem qualquer dependência de arredondamento: Basta adicionar mais um parâmetro igual a zero para o construtor CTime
. Este forças ambas as vezes para a hora padrão (não horário de verão). O valor padrão para esse parâmetro é -1, que significa "calcular automaticamente se o horário de verão está em vigor."
// Discard hours, minutes, seconds, and daylight savings time
CTime startDay(start.GetYear(), start.GetMonth(), start.GetDay(), 0, 0, 0, 0);
CTime endDay(end.GetYear(), end.GetMonth(), end.GetDay(), 0, 0, 0, 0);
// Get number of days apart
CTimeSpan span = endDay - startDay;
int nDays = span.GetDays();
testado e funciona.