time.h
. La prima funzione che presentiamo è la seguente:
time_t time (time_t* risultato) |
time
è time_t
, un tipo a noi sconosciuto. In realtà non si tratta altro che del sinonimo di un tipo primitivo (spesso long int), il quale assume un significato diverso a seconda del compilatore e della macchina sulla quale esso funziona. L'unico argomento accettato dalla funzione è un puntatore a time_t
: se esso è non nullo allora il valore di ritorno della funzione viene assegnato anche a risultato. Se, per qualche motivo indipendente dalla nostra volontà, non sono disponibili data e ora locali viene tornato il codice di errore -1
. Il valore del ritorno di time
corrisponde di solito al numero di secondi trascorsi dalla mezzanotte del 1 gennaio 1970, secondo il Coordinated Universal Time; vediamo il seguente esempio:
// ex8_5_1 #include <iostream.h> #include <time.h> void main() { time_t risultato; time_t ora = time (0); time (&risultato); if ( ora != (time_t)(-1) ) cout << ora << "\n" << risultato << "\n"; cout << "spazio occupato da time_t: " << sizeof(time_t); }
esempio di output:
951300989
951300989
spazio occupato da time_t: 4
Prima osservazione: il numero di bytes occupato da una variabile time_t
è lo stesso occupato dal un long int; una domanda che è lecito porsi è la seguente: cosa succederà quanto il numero di secondi trascorsi dal 1/1/1970 non potrà più essere contenuto in un long int? Un numero intero con segno sappiamo essere uguale massimo a , dunque passati circa 2 miliardi di secondi (più di 68 anni) dal 1/1/1970 ci troveremmo in un bel problema, del tutto simile al celebrerrimo Y2K bug. Tuttavia l'eventualità che nel 2038 si usino ancora macchine che memorizzano numeri interi su 32 bit è irrealizzabile; si tenga presente che già memorizzando gli interi su ``solo'' 64 bit potremmo stare tranquilli per 73'117'802'169 anni, ben più dell'età dell'universo. Seconda osservazione: abbiamo a disposizione due metodi per acquisire l'ora locale, come vediamo nell'esempio
ex8_5_1.cpp
; il primo consiste nell'utilizzare il valore di ritorno di time
, il secondo nel passare per indirizzo una variabile alla stessa funzione; il risultato, come ovvio, è lo stesso.
Possiamo dunque avere a nostra disposizione il numero di secondi trascorsi dalla mezzanotte del 1/1/1970; tale informazione tuttavia ci è ben poco utile: in teoria siamo costretti tutte le volte che vogliamo trovare l'ora locale a effettuare complicati calcoli per ricavarla. Ciò non è in pratica necessario perché esiste una funzione di libreria che effettua questo lavoro per noi:
struct tm* localtime (const time_t* t) |
time_t
, presumibilmente ricavata tramite time
, in un puntatore alla struttura tm
; tale struct è definita all'interno della libreria time.h
e contiene i seguenti campi8.5:
int tm_sec |
secondi | |
int tm_min |
minuti | |
int tm_hour |
ore (0-23) | |
int tm_mday |
giorno del mese (1-31) | |
int tm_mon |
mese dell'anno (0-11) | |
int tm_year |
anno dopo il 1900 | |
int tm_wday |
giorno della settimana da Domenica (0-6) | |
int tm_yday |
giorno dell'anno dal 1 Gennaio (0-365) | |
int tm_isdst |
ora legale |
L'unica nota riguarda il campo tm_isdst
, il quale controlla l'ora legale: se il valore restituito è positivo allora l'ora legale è in vigore, se esso è nullo non lo è, se infine il valore è negativo allora non è disponibile nessuna informazione sull'ora legale. Vediamo un semplice esempio:
// ex8_5_2 #include <iostream.h> #include <time.h> void main() { time_t ora_corrente; tm* ora_locale; ora_corrente = time(0); ora_locale = localtime (&ora_corrente); char giorno_settimana[11]; char ora_legale[40]; switch (ora_locale->tm_wday) { case 0: strcpy (giorno_settimana, "Domenica"); break; case 1: strcpy (giorno_settimana, "Lunedi`"); break; case 2: strcpy (giorno_settimana, "Martedi`"); break; case 3: strcpy (giorno_settimana, "Mercoledi`"); break; case 4: strcpy (giorno_settimana, "Giovedi`"); break; case 5: strcpy (giorno_settimana, "Venerdi`"); break; case 6: strcpy (giorno_settimana, "Sabato"); break; } if (ora_locale->tm_isdst > 0) strcpy (ora_legale, "ora legale in vigore"); else if (ora_locale->tm_isdst == 0) strcpy (ora_legale, "ora legale NON in vigore"); else strcpy (ora_legale, "nessuna informazione sull'ora legale"); cout << "sono le ore " << ora_locale->tm_hour << ":" << ora_locale->tm_min << "," << ora_locale->tm_sec << "\ndel giorno " << giorno_settimana << "," << ora_locale->tm_mday << "/" << ora_locale->tm_mon << "/" << ora_locale->tm_year + 1900 << "\n" << ora_legale << "\n"; }
esempio di output:
sono le ore 12:2,33
del giorno Mercoledi`,23/1/2000
ora legale NON in vigore
I passaggi da effettuare se si vuole avere a disposizione ora e data locali sono i seguenti: dichiarare una variabile time_t
nella quale memorizzare il numero di secondi trascorsi dalla mezzanotte del 1/1/1970, tramite la funzione time
; dichiarare una variabile di tipo puntatore a struttura tm
nella quale memorizzare le informazioni dettagliate su data e ora tramite la funzione localtime
; sfruttare gli appropriati campi della struttura tm
.
Vediamo ancora due funzioni che risultano spesso utili:
time_t mktime (struct tm* t)
char* ctime (const time_t* t) |
localtime
: converte una struttura tm
, passata per indirizzo, in una variabile time_t
. La nota più interessante riguarda il fatto che, nella conversione, i campi mancanti vengono completati. Ad esempio se noi vogliamo sapere il giorno della settimana di una certa data, basta creare una struttura tm
, convertirla in time_t
tramite la funzione mktime
e riconvertirla tramite localtime
; vediamo un esempio:
// ex8_5_3 #include <iostream.h> #include <time.h> void main() { tm* ora_corrente = new tm; cout << "giorno del mese? "; cin >> ora_corrente->tm_mday; cout << "mese dell'anno? "; cin >> ora_corrente->tm_mon; cout << "anno (4 cifre)? "; cin >> ora_corrente->tm_year; ora_corrente->tm_mon -= 1; ora_corrente->tm_year -= 1900; time_t t = mktime (ora_corrente); ora_corrente = localtime (&t); cout << "il giorno della settimana e`: " << ora_corrente->tm_wday; }
esempio di output:
giorno del mese? 1
mese dell'anno? 1
anno (4 cifre)? 2000
il giorno della settimana e`: 6
Si noti che abbiamo dovuto togliere una unità dal campo tm_mon
, perché di solito noi indichiamo i mesi da 1 a 12 piuttosto che da 0 a 11, e abbiamo dovuto sottrarre al campo tm_year
1900, perché l'anno viene memorizzato a partire proprio da 1900 nella struttura tm
. Nel caso la funzione mktime
fallisca la conversione, essa torna il codice di errore -1
.
La funzione ctime
converte un puntatore costante a time_t
in una stringa contenente le principali informazioni su data e ora; vediamo un esempio8.6
// ex8_5_4 #include <iostream.h> #include <time.h> void main() { time_t ora= time(0); cout << ctime(&ora); }
esempio di output:
Wed Feb 23 12:24:03 2000
Nella libreria GNU, conforme alle specifiche ANSI C Standard, i simboli utilizzati per i giorni della settimana sono, a partire dal Domenica, i seguenti: `Sun', `Mon', `Tue', `Wed', `Thu', `Fri', `Sat'; per i quanto riguarda i mesi abbiamo: `Jan', `Feb', `Mar', `Apr', `May', `Jun', `Jul', `Aug', `Sep', `Oct', `Nov', `Dec'.
time_t
(per indirizzo) e le sommi esattamente un giorno solare; si verifichi il funzionamento con la ctime
;