Quanti giorni tra due date: difftime

Vogliamo calcolare la differenza in giorni tra due dati istanti.

Per istante intendiamo il numero di secondi passati dalla mezzanotte del primo gennaio 1970 UTC (l'inizio del tempo UNIX), un valore integrale che viene gestito da variabili di tipo time_t.

Come spesso accade, risolviamo il nostro problema riducendolo a uno più semplice, per poi adattare il risultato ai nostri bisogni.

Calcoliamo quindi i secondi di differenza tra due tempi usando la funzione difftime, definita in ctime con questo prototipo:

double difftime(time_t t2, time_t t1);

dove t2 é il tempo più lontano dall'inizio del tempo. Se si mette in t2 il primo tra i due tempi si otterrà un risultato negativo.

Dividiamo poi il risultato per il numero di secondi in un giorno, 86400, ottenendo il risultato atteso:

double days = difftime(end, start) / 86400;

Notiamo che il numero di giorni é espesso come numero decimale, dato che si fa una differenza al secondo, quindi si ottiene una risposta che potrebbe essere del tipo "circa otto giorni e mezzo".

Per passare da una data in formato leggibile a un umano a una nel formato accettato da difftime usiamo la funzione mktime(), anch'essa definita in ctime:

time_t mktime(tm* pTime);

che non fa altro che convertire il contenuto di un oggetto di tipo tm nel numero di secondi passati dall'inizio del tempo UNIX. In caso di errore la funzione ritorna -1.

La creazione di un oggetto di tipo tm, una struttura definita in ctime, sarebbe banale, se non ci fosse da tener presente alcune sottigliezze.

Bisogna infatti specificare l'attimo definendo tutte le sue componenti in un modo che non é sempre naturale.
Secondi, minuti e ore non danno problemi - anche se vanno indicati come li ho scritti, non partendo dalle ore, come sembrerebbe spontaneo.
Segue poi il giorno del mese, nessun problema.
Poi il mese, partendo da Gennaio che vale 0 fino a dicembre che é 11.
E infine l'anno a partire dal 1900 (ovvero, per il 2000 occorre mettere 100).

Dunque, per creare un oggetto tm corrispondente alla mezzanotte del 2 ottobre 2000 dobbiamo scrivere:

tm tmStart = {0, 0, 0, 2, 9, 100};

Per testare la funzionalità scriviamo questa funzioncina:

#include
#include

using namespace std;
// ...
void testDiff() {
tm tmStart = {0, 0, 0, 2, 9, 100};
time_t start = mktime(&tmStart);
if(start == -1) {
cout << "Bad start date." << endl;
return;
}

tm tmEnd = {0, 0, 0, 3, 7, 109};
time_t end = mktime(&tmEnd);
if(end == -1) {
cout << "Bad end date." << endl;
return;
}

double days = difftime(end, start) / 86400;
cout << "difference = " << days << " days" << endl;
return;
}

Nessun commento:

Posta un commento