Domanda

Ho trovato un bug in un vecchio programma MFC C ++ che calcola un offset (in giorni) per una data data da una data base fissa. Stavamo vedendo risultati che erano stati annullati da uno per qualche motivo e l'ho rintracciato fino a dove il programmatore originale aveva usato il metodo CTimeSpan.GetDays (). Secondo la documentazione :

  

Notare che l'ora legale può far sì che GetDays restituisca un risultato potenzialmente sorprendente. Ad esempio, quando è in vigore l'ora legale, GetDays riporta il numero di giorni tra il 1 aprile e il 1 maggio come 29, non 30, poiché un giorno di aprile viene abbreviato di un'ora e pertanto non viene considerato come un giorno completo.

La mia soluzione proposta è usare invece (obj.GetTotalHours () + 1) / 24 . Penso che coprirebbe tutti i problemi poiché si tratta di un processo batch che viene eseguito all'incirca alla stessa ora ogni giorno, ma ho pensato di chiedere alle persone intelligenti qui prima di implementarlo se potesse esserci un modo migliore.

Questo è solo un problema secondario, ma sono anche curioso di sapere come gestirlo se il programma potesse essere eseguito in qualsiasi momento.

È stato utile?

Soluzione

La correzione funziona bene per ottenere il numero di interi periodi di 24 ore tra due volte, purché gli eventi si verifichino alla stessa ora ogni giorno. Altrimenti che " + 1 " nell'espressione potrebbe portare a un errore off-by-one.

A volte non ti interessa a che ora del giorno si è verificato l'evento, vuoi solo sapere in quale giorno. In tal caso, è necessario azzerare le ore, i minuti e i secondi, quindi utilizzare la formula:

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;

Altri suggerimenti

Una piccola modifica a ciò che Mark ha suggerito e funziona senza fare affidamento sull'arrotondamento: basta aggiungere un altro parametro di zero al costruttore CTime . Ciò costringe entrambe le volte ad essere in orario standard (non l'ora legale). Il valore predefinito per quel parametro è -1 che significa "Calcola automaticamente se è in vigore l'ora legale." & 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();

Testato e funzionante.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top