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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top