La data e l'ora sono rappresentate in una forma codificata (o compressa) allo scopo di occupare un solo long integer.
Una data ammessa deve essere compresa tra 1-1-1979 e 19-01-2038
Il tipo di dati con cui si codifica una data è time_t, che è equivalente a long int.
Per elaborare date occorre includere il file di intestazione time.h (automaticamente incluso con iostream.
Nel file header time.h è definita anche la struttura per mantenere la data decodificata:
struct tm { int tm_sec; /* Secondi: 0-59 */ int tm_min; /* Minuti: 0-59 */ int tm_hour; /* Ora: 0-23 */ int tm_mday; /* Giorno del mese: 1-31 */ int tm_mon; /* Mese dell'anno: 0-11 (0=>Gennaio, 11=>Dic */ int tm_year; /* Numero di anni trascorsi dal 1900 */ int tm_wday; /* Giorno della settimana da 0=>Domenica, 6=>Sabato */ int tm_yday; /* Giorno dell'anno a partire dal 1 gennaio: 0-365 */ int tm_isdst; /* +1 si considera l'ora legale, 0 ora legale ignorata, };
Le funzioni che operano sulle date, servendosi delle variabili di tipo struct time_t e tm sono:
Lettura della data e dell'ora di sistema
time_t time(*time_t)
time è una funzione che riceve il puntatore ad una variabile di tipo time_t e restituisce un valore di tipo time_t
Di solito il parametro è il puntatore NULL o il valore 0, se invece è un puntatore diverso da NULL allora il risultato viene messo anche nella variabile puntata. Per esempio:
secondi = time(0);
Nella variabile secondi viene scritta, in forma codificata, la data corrente, espressa con il numero di secondi trascorsi dalla mezzanotte del 1/1/1970, letta dall'orologio di sistema.
Decodifica della data e dell'ora
struct tm * localtime (const time_t *time)
localtime riceve il parametro costante, che rappresenta una data in forma codificata, e restituisce il puntatore ad una variabile di tipo tm, in cui è rappresentata la data in forma decodificata.
Nella decodifica si tiene conto delle impostazioni locali del sistema operativo (il fuso orario e l'eventuale ora legale impostata).
Per esempio:
time_t secondi;
secondi è una variabile avente la struttura time_t (data compatta)
tm *ora;
ora è un puntatore ad un record con data e ora decodificata
secondi = time(0); cout << "Numero di secondi trascorsi dalla mezzanotte dell'1/1/1970: " << secondi << endl;
La funzione time legge la data e l'ora di sistema e la scrive in forma compressa nella variabile secondi
ora = localtime(&secondi); cout << "Ora locale: " << ora->tm_hour << ':' << ora->tm_min << ':' << ora->tm_sec << endl;
la funzione localtime riceve l'indirizzo della variabile secondi e riempie i campi del record ora con i valori decompressi della data e dell'ora
time_t mktime (struct tm *recdataora)
La funzione mktime riceve come parametro il puntatore ad un record (avente i campi della struttura descritta da
tm) e restituisce una data compatta.
L'operazione di codifica non prende in considerazione i campi tm_wday e tm_yday ma solo quelli corrispondenti a anno, mese, giorno, ora, minuti e secondi.
Creare un nuovo progetto C++. Per il momento non modificare il file contenente la funzione main.
Aggiungere un nuovo file al progetto: File->Nuovo->File sorgente e alla domanda: "aggiungere al progetto?" rispondere Sì.
class Data { public: Data(int g, int m, int a); // Costruttore Data(); // Costruttore di default void mostra(); // void calcGiorno(); ~Data(); // Distruttore private: int giorno, mese, anno; // campi privati static char *nomeMese[12]; static char *nomeGiorno[7]; static int lung[12]; inline int max( int a, int b) { if( a > b ) return a; return b; } inline int min( int a, int b) { if( a < b ) return a; return b; } };
I campi membro giorno, mese e anno, essendo privati, sono accessibili solo alle funzioni della classe.
Anche gli array di puntatori a char nomeMese, nomeGiorno e l'array di interi lung sono accessibili aolo alle funzioni della classe. Inoltre questi array sono dichiarati static perchè verranno creati un'unica volta
La classe Data rappresenta un nuovo tipo, definito dal programmatore, con cui si possono creare variabili (dette oggetti o istanze) del tipo Data. Ad esempio un oggetto potrebbe memorizzare la data di scadenza dell'assicurazione, un altro oggetto potrebbe memorizzare la data di revisione del veicolo, ecc... Ogni oggetto creato possiederà i propri campi giorno, mese e anno.
Gli array nomeMese, nomeGiorno e lung, invece verranno creati un'unica volta e saranno comuni a tutti gli oggetti di classe Data. Se si dovesse decidere di cambiare la forma in cui sono scritti i nomi dei giorni (ad esempio dalla forma estesa alla forma abbreviata), è sufficiente che lo si faccia, tramite una funzione membro, da un oggetto che la modifica viene vista anche dagli altri oggetti.
Aggiungere un nuovo file al progetto: File->Nuovo->File sorgente e alla domanda: "aggiungere al progetto?" rispondere Sì.
#include <iostream> #include "data.h" using namespace std; char* Data::nomeMese[] = { "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre","Ottobre","Novembre","Dicembre" }; char* Data::nomeGiorno[] = {"Dom", "Lun", "Mar", "Mere", "Gio", "Ven", "sab"}; int Data::lung[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; Data::Data( int g, int m, int a ) { mese = max( 1, m ); mese = min( mese, 11); giorno = max( 1, g ); giorno = min( giorno, lung[mese] ); anno = max( 1, a ); } void Data::mostra() { cout << "data: " << giorno << ' ' << nomeMese[mese] << ' ' << anno; } Data::~Data() { } Data::Data() { time_t secondi; tm *ora; secondi = time(0); ora = localtime(&secondi); cout << "Ora: " << ora->tm_hour << ':' << ora->tm_min << ':' << ora->tm_sec << endl; giorno = ora->tm_mday; mese = ora->tm_mon; anno = ora->tm_year + 1900; } void Data::calcGiorno () { time_t ggmmaa; struct tm *recData; time (&ggmmaa ); recData = localtime ( &ggmmaa ); recData->tm_mday = giorno; recData->tm_mon = mese - 1; recData->tm_year = anno - 1900; mktime (recData); cout << endl << giorno << "/" << mese << "/" << anno << ": " << nomeGiorno[recData->tm_wday] << endl; }
#include <iostream> #include "data.h" using namespace std; int main() { Data Oggi, Compleanno(15, 7, 2013); Oggi.mostra(); Compleanno.calcGiorno(); system("Pause"); return EXIT_SUCCESS; }
Calcolare il numero di giorni mancanti al compleanno.
Calcolare la data del prossimo lunedì
Calcolare il calendario del mese prossimo.