Tips&Tricks I trucchi del mestiere

 

Una classe in C++ per manipolare le date

Una classe Data che pu≥ risultare comoda per chi fa programmi che utilizzano questo tipo di informazione.
Tip fornito dal Sig. Eugenio Dei Giudici

// FILE Data.h - Header File

#ifndef DATAH
#define DATAH

#include 
#include 

using namespace std;

class Data {

// Operatore d'uscita (output)
friend ostream& operator<<(ostream&, const Data&);
// Operatore d'ingresso (input)
friend istream& operator>>(istream&, Data&);
// Operatori di confronto
friend bool operator==(const Data&, const Data&);
friend bool operator!=(const Data&, const Data&);
friend bool operator<(const Data&, const Data&);
friend bool operator<=(const Data&, const Data&);
friend bool operator>(const Data&, const Data&);
friend bool operator>=(const Data&, const Data&);

public:
		Data(int,int,int);				// Costruttore
		Data(const Data&);			// Costruttore di copia
		Data();					// Costruttore di default

		Data& operator=(const Data&);	// Operatore d'assegnamento

		int getAnno() const { return anno; }	// Funzioni che restituiscono
		int getMese() const { return mese; }	// i valori delle variabili
		int getGiorno() const { return giorno; }	// di stato

		void modG(int);				// Funzioni atte
		void modM(int);				// a modificare
		void modA(int);				// le variabili di stato

private:
		int anno;					// Variabili
		int mese;					// di
		int giorno;					// stato

// Funzione di verifica dell'effettiva esattezza di una possibile Data
		bool controlla (int,int,int);	

}; // Data

#endif

// File Data.cpp - Implementazione

#include "Data.h"
#include 

Data::Data(int g,int m,int a) {
	if(!controlla(g,m,a)) throw new exception();
	giorno=g;
	mese=m;
	anno=a;
} // costruttore

Data::Data(const Data& d) {
	giorno=d.giorno;
	mese=d.mese;
	anno=d.anno;
} // costruttore di copia

Data::Data() {
	int g;
	int m;
	int a;
	time_t t=time(NULL);
	char* s=ctime(&t);	/* stringa contenente la data corrente sottoforma di:
				giorno_della_settimana mese giorno ora anno*/
	char* p;			/* puntatore a carattere necessario a puntare
					il primo carattere utile dei token */
	p=strtok(s," ");	// prendo il primo token che non mi serve
	p=strtok(NULL," ");	/* prendo il token successivo sostituendo NULL al carattere 
				   \0 del token precedente, modificando cos∞ la stringa di					   partenza */
	if(strcmp(p,"Jan")==0) m=1;
	if(strcmp(p,"Feb")==0) m=2;
	if(strcmp(p,"Mar")==0) m=3;
	if(strcmp(p,"Apr")==0) m=4;
	if(strcmp(p,"May")==0) m=5;
	if(strcmp(p,"Jun")==0) m=6;
	if(strcmp(p,"Jul")==0) m=7;
	if(strcmp(p,"Aug")==0) m=8;
	if(strcmp(p,"Sep")==0) m=9;
	if(strcmp(p,"Oct")==0) m=10;	
	if(strcmp(p,"Nov")==0) m=11;
	if(strcmp(p,"Dec")==0) m=12;
	p=strtok(NULL," ");	// prendo il token col giorno
	g=atoi(p);		// converto il giorno da string in int
	p=strtok(NULL," ");  // prendo il token con l'ora e lo scarto subito
	p=strtok(NULL," ");	// prendo il token con l'anno
	a=atoi(p);		// converto l'anno da string in int
	if(!controlla(g,m,a)) throw new exception();
	giorno=g;
	mese=m;
	anno=a;	
} // costruttore di default (ritorna la data corrente dell'orologio di sistema)

Data& Data::operator=(const Data& d) {
	giorno=d.giorno;
	mese=d.mese;
	anno=d.anno;
	return *this;
} // operator=

void Data::modG(int g) {
	if (!controlla(g, mese, anno)) throw new exception();
	giorno=g;
} // modG

void Data::modM(int m) {
	if (!controlla(giorno, m, anno)) throw new exception();
	mese=m;
} // modM

void Data::modA(int a) {
	if (!controlla(giorno, mese, a)) throw new exception();
	anno=a;
} // modA

bool Data::controlla (int g,int m,int a) {
	if (g<1 || g>31) return false;
	if (m<1 || m>12) return false;
	if (a<=-1000000000 || a>=1000000000) return false;	// limiti totalmente arbitrari (cifra tonda!)
	if (g==31 && (m==4 || m==6 || m==9 || m==11) ) return false;
	if (m==2) 
		if (g>29 || g==29 && a%4!=0 ) return false;
	return true;
} // controlla

// Overloading degli operatori

// Operatore d'uscita (output)
ostream& operator<<(ostream& os, const Data& d) {
	os<<d.giorno<<"/"<<d.mese<<"/"<<d.anno;
	return os;
} // operator><

// Operatore d'ingresso (input)
istream& operator>>(istream& is, Data& d) {
	int g,m,a;
	char* c=new char[50];
	cout<<"Inserisci il giorno: "; 
	is.getline(c,50);
	g=atoi(c);
	cout<<"Inserisci il mese: ";
	is.getline(c,50);
	m=atoi(c);
	cout<<"Inserisci l'anno: ";
	is.getline(c,50);
	a=atoi(c);
	delete [] c;
	if(!d.controlla(g,m,a)) throw new exception();
	d.modG(g);
	d.modM(m);
	d.modA(a);
	return is;
} // operator>>

// Operatori di confronto
bool operator==(const Data& d1, const Data& d2) {
	return (d1.giorno==d2.giorno && d1.mese==d2.mese && d1.anno==d2.anno);
} // operator==

bool operator!=(const Data& d1, const Data& d2) {
	return (d1.giorno!=d2.giorno || d1.mese!=d2.mese || d1.anno!=d2.anno);
} // operator!=

bool operator<(const Data& d1, const Data& d2) {
	return (d1.anno<d2.anno || d1.anno==d2.anno && d1.mese<d2.mese || 
			d1.anno==d2.anno && d1.mese==d2.mese && d1.giorno<d2.giorno);
} // operator<

bool operator<=(const Data& d1, const Data& d2) {
	return (d1.anno<d2.anno || d1.anno==d2.anno && d1.mese<d2.mese || 
			d1.anno==d2.anno && d1.mese==d2.mese && d1.giorno<d2.giorno ||
			d1.giorno==d2.giorno && d1.mese==d2.mese && d1.anno==d2.anno);
} // operator<=

bool operator>(const Data& d1, const Data& d2) {
	return (d1.anno>d2.anno || d1.anno==d2.anno && d1.mese>d2.mese || 
			d1.anno==d2.anno && d1.mese==d2.mese && d1.giorno>d2.giorno);
} // operator>

bool operator>=(const Data& d1, const Data& d2) {
	return (d1.anno>d2.anno || d1.anno==d2.anno && d1.mese>d2.mese || 
			d1.anno==d2.anno && d1.mese==d2.mese && d1.giorno>d2.giorno ||
			d1.giorno==d2.giorno && d1.mese==d2.mese && d1.anno==d2.anno);
} // operator>=