Pregunta

Encontré un error en un antiguo programa MFC de C ++ que tenemos que calcula un desplazamiento (en días) para una fecha determinada desde una fecha base fija. Estábamos viendo resultados que estaban desactivados por uno por alguna razón, y lo rastreé hasta donde el programador original había usado el método CTimeSpan.GetDays (). De acuerdo con la documentación :

  

Tenga en cuenta que el horario de verano puede hacer que GetDays devuelva un resultado potencialmente sorprendente. Por ejemplo, cuando el horario de verano está vigente, GetDays informa que el número de días entre el 1 de abril y el 1 de mayo es de 29, no de 30, porque un día en abril se acorta en una hora y, por lo tanto, no cuenta como un día completo.

Mi solución propuesta es utilizar (obj.GetTotalHours () + 1) / 24 . Creo que eso abarcaría todos los problemas, ya que se trata de un trabajo por lotes que se ejecuta aproximadamente a la misma hora todos los días, pero pensé que le preguntaría a las personas inteligentes de aquí antes de implementarlo si hay una manera mejor.

Esto es solo un problema secundario, pero también tengo curiosidad por saber cómo se manejaría si el programa pudiera ejecutarse en cualquier momento.

¿Fue útil?

Solución

Su corrección funciona bien para obtener la cantidad de períodos completos de 24 horas entre dos veces, siempre que los eventos se produzcan a la misma hora cada día. De lo contrario, " + 1 " en la expresión podría dar lugar a un error off-by-one.

A veces no le importa a qué hora del día ocurrió el evento, solo quiere saber qué día. En ese caso, necesita poner a cero las horas, los minutos y los segundos y luego usar su 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;

Otros consejos

Un cambio menor a lo que Mark sugirió y funciona sin depender del redondeo: simplemente agregue un parámetro más de cero al constructor CTime . Esto obliga a las dos veces a estar en hora estándar (no a la luz del día). El valor predeterminado para ese parámetro es -1, que significa " Calcular automáticamente si el horario de verano está vigente. & Quot;

// 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();

Probado y funciona.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top