Hola, esta clase fecha es de un curso que había hecho en mi facultad. La clase no fue escrita por mi, yo sólo agregué las funciones a lo último.
Pero me doy cuenta de la utilidad que puede tener para gente iniciada que tiene esta clase de problemas que sus profesores le piden ejercicios con fechas. Les puede servir.
//
//Puede utilizarse para fechas desde el 01/01/1900
class Fecha
{
private:
int dia;
int mes;
int año;
// bool esbisiesto(int);
void NumeroSerieaFecha(int);
public:
bool esbisiesto(int);
Fecha(int d=0,int m=0,int a=0);
int getDia(){return dia;}
int getMes(){return mes;}
int getAnio(){return año;}
void setDia(int d){dia=d;}
void setMes(int m){mes=m;};
void setAnio(int a){año=a;}
void MostrarFecha();
void MostrarFechaTexto();
int NumeroSerie();
bool operator >(Fecha &);
bool operator ==(Fecha &);
Fecha operator+(int);
int operator -(Fecha &);
void operator +=(int);
int operator==(char *);
friend istream & operator>>(istream &, Fecha &);
friend ostream & operator<<(ostream &, Fecha &);
int cantDiasMes();
int cantDiasHabilesMes();
int cantAniosHastaHoy();
bool EsSuperiorAFechaActual(Fecha fx);
int FechaEntreDosFechas(Fecha inicio_de_promocion, Fecha fin_de_promocion, Fecha fecha_de_compra );
unsigned int CalcularEdad(Fecha birthdate);
};
Fecha::Fecha(int d,int m,int a)
{//El constructor asigna los valores recibidos, si le son pasados como parámetros
if(d!=0)
{
dia=d;mes=m;año=a;//¿Qué modificación habría que hacerle al constructor para
} // garantizar que no se asignen valores absurdos? Ej.:65/65/-12
else //si no recibe valores asigna por defecto la fecha actual
{
time_t tiempo;
struct tm *tmPtr;
tiempo = time(NULL);
tmPtr = localtime(&tiempo);
año=tmPtr->tm_year+1900;
mes=tmPtr->tm_mon+1;
dia=tmPtr->tm_mday;
}
}
//Devuelve true si el año recibido es bisiesto.
bool Fecha::esbisiesto(int a)
{
bool bisiesto=false;
if(a%4==0)
bisiesto=true;
if((a%100==0) && (a%400!=0))
bisiesto=false;
return bisiesto;
}
//Muestra la fecha en formato número. Ej.: 15/10/2008
void Fecha::MostrarFecha()
{
cout<<dia<<"/"<<mes<<"/"<<año<<endl;
}//¿Qué modificación habría que hacer para que siempre muestre DD/MM/AAAA?
//Devuelve 1 si la fecha coincide con una cadena que representa un día de la semana
int Fecha::operator==(char *diaSemana)
{
int cantdias=NumeroSerie()-1;//cantidad de días transcurridos desde 01/01/1900
//El 01/01/1900 fue Lunes
int numerodia=cantdias%7;
char mdia[7][10];
strcpy(mdia[0],"Lunes");
strcpy(mdia[1],"Martes");
strcpy(mdia[2],"Miercoles");
strcpy(mdia[3],"Jueves");
strcpy(mdia[4],"Viernes");
strcpy(mdia[5],"Sábado");
strcpy(mdia[6],"Domingo");
if(strcmp(mdia[numerodia],diaSemana)==0)
return 1;
return 0;
}
//Muestra la fecha indicando en texto el día y el mes.Ej.: Lunes 1 de enero de 1900
void Fecha::MostrarFechaTexto()
{
char mmes[12][11];
strcpy(mmes[0],"Enero");
strcpy(mmes[1],"Febrero");
strcpy(mmes[2],"Marzo");
strcpy(mmes[3],"Abril");
strcpy(mmes[4],"Mayo");
strcpy(mmes[5],"Junio");
strcpy(mmes[6],"Julio");
strcpy(mmes[7],"Agosto");
strcpy(mmes[8],"Septiembre");
strcpy(mmes[9],"OCtubre");
strcpy(mmes[10],"Noviembre");
strcpy(mmes[11],"Diciembre");
int cantdias=NumeroSerie()-1;//cantidad de días transcurridos desde 01/01/1900
//El 01/01/1900 fue Lunes
int numerodia=cantdias%7;
char mdia[7][10];
strcpy(mdia[0],"Lunes");
strcpy(mdia[1],"Martes");
strcpy(mdia[2],"Miercoles");
strcpy(mdia[3],"Jueves");
strcpy(mdia[4],"Viernes");
strcpy(mdia[5],"Sábado");
strcpy(mdia[6],"Domingo");
cout<<endl<<mdia[numerodia]<<" "<<dia<<" de "<<mmes[mes-1]<<" de "<<año<<endl;
}
//Devuelve la cantidad de días transcurridos desde el 01/01/1900
int Fecha::NumeroSerie()
{
int cont=0,i;
for(i=1900;i<año;i++) if(esbisiesto(i)) cont++;
int vmes[]={31,28,31,30,31,30,31,31,30,31,30,31},suma=0;
if(esbisiesto(año)) vmes[1]=29;
for(i=0;i<mes-1;i++) suma+=vmes[i];
int cantdias=(año-1900)*365+cont+suma+dia;
return cantdias;
}
//Sobrecargas
bool Fecha::operator>(Fecha &obj)
{
if(NumeroSerie()>obj.NumeroSerie())
return true;
return false;
}
bool Fecha::operator==(Fecha &obj)
{
if(NumeroSerie()==obj.NumeroSerie()) return true;
//Otra posibilidad
//if(dia==obj.dia && mes==obj.mes && año==obj.año)
// return true;
return false;
}
void Fecha::NumeroSerieaFecha(int ns)
{
int suma=0, dia_adicional, suma_ant;
int anio_real=1900;
while(ns>suma)
{
dia_adicional=(esbisiesto(anio_real)?1:0);
suma_ant=suma;
suma+=365+dia_adicional;
anio_real++;
}
año=anio_real-1;
//Cantidad de días pasados desde año
int dias_anio_actual=ns-suma_ant,i=0;
int vmes[]={31,28,31,30,31,30,31,31,30,31,30,31};
if(esbisiesto(año)) vmes[1]=29;
suma=0;
while(dias_anio_actual>suma) suma+=vmes[i++];
mes=i;
dia=dias_anio_actual-(suma-vmes[i-1]);
}
void Fecha::operator +=(int masdias)
{
int ns=NumeroSerie()+masdias;
NumeroSerieaFecha(ns);
}
istream & operator>>(istream &entra, Fecha &f)
{
cout<<"Ingrese el dia: ";
entra>>f.dia;
cout<<"Ingrese el mes: ";
entra>>f.mes;
cout<<"Ingrese el año: ";
entra>>f.año;
return entra;
}
ostream & operator<<(ostream &sale, Fecha &f)
{
cout<<"Dia: ";
sale<<f.dia<<endl;
cout<<"Mes: ";
sale<<f.mes<<endl;
cout<<"Año: ";
sale<<f.año<<endl;
return sale;
}
Fecha Fecha::operator+(int masdias)
{
Fecha aux;
int ns=NumeroSerie()+masdias;
aux.NumeroSerieaFecha(ns);
return aux;
}
int Fecha::operator -(Fecha &obj)
{
return NumeroSerie()-obj.NumeroSerie();
}
int Fecha::cantDiasMes()
{
int vmes[]={31,28,31,30,31,30,31,31,30,31,30,31};
if(esbisiesto(año)) vmes[1]=29;
return vmes[mes-1];
}
// Devuelve la cantidad de días hábiles del mes correspondiente a la fecha
// No tiene en cuenta si en el mes hay o no feriados
// Una posibilidad es que se identifique en una matriz los días feriados del año
// y se compare cada día con esa matriz
int Fecha::cantDiasHabilesMes()
{
int totDias=cantDiasMes();
int dia, cant=0;
Fecha aux=*this;
for(int i=1;i<=totDias;i++)
{
dia=(aux.NumeroSerie()-1)%7;
if(dia<5) cant++;
aux+=1;
}
return cant;
}
//Devuelve la cantidad de años entre una fecha y el día actual
int Fecha::cantAniosHastaHoy()
{
Fecha aux; //por usar un constructor por defecto tiene la fecha de hoy;
int cant=aux.año-año;
if(mes>aux.mes) return cant-1;
if(mes==aux.mes && dia>aux.dia) return cant-1;
return cant;
}
////////////////////////////////////////////////////////////////////////////////////
bool Fecha::EsSuperiorAFechaActual(Fecha fx){
SYSTEMTIME time;
::GetLocalTime(&time);
//
//la promocion debe ser superior a la fecha actual..
if( fx.getAnio()>time.wYear ||
(fx.getAnio()==time.wYear && fx.getMes()>time.wMonth) ||
(fx.getAnio()==time.wYear && fx.getMes()==time.wMonth && fx.getDia()>time.wDay))
{
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////
int Fecha::FechaEntreDosFechas(Fecha inicio_de_promocion, Fecha fin_de_promocion, Fecha fecha_de_compra ){
//---------------
// PARTE1
if(fecha_de_compra.getAnio() < inicio_de_promocion.getAnio() )return 0;
if(fecha_de_compra.getAnio() == inicio_de_promocion.getAnio() ){
if(fecha_de_compra.getMes() < inicio_de_promocion.getMes())return 0;
}
if(fecha_de_compra.getAnio() == inicio_de_promocion.getAnio() ){
if(fecha_de_compra.getMes() == inicio_de_promocion.getMes())
if(fecha_de_compra.getDia() < inicio_de_promocion.getDia())return 0;
}
//------------------
// PARTE2
if(fecha_de_compra.getAnio() > fin_de_promocion.getAnio() )return 0;
if(fecha_de_compra.getAnio() == fin_de_promocion.getAnio() ){
if(fecha_de_compra.getMes() > fin_de_promocion.getMes())return 0;
}
if(fecha_de_compra.getAnio() == fin_de_promocion.getAnio() ){
if(fecha_de_compra.getMes() == fin_de_promocion.getMes())
if(fecha_de_compra.getDia() > fin_de_promocion.getDia())return 0;
}
//-----------
return 1;
}
///////////////////////
/*
unsigned int Fecha::CalcularEdad(Fecha birthdate)
{
int AnioActual, AA, MesActual, MM, DiaActual, DD;
int año, Mes, Dia;
int MonthDays[2][12] = {
{31, 28, 30, 31, 30, 31, 31, 31, 30, 31, 30, 31},
{31, 29, 30, 31, 30, 31, 31, 31, 30, 31, 30, 31}
};
SYSTEMTIME time;
GetLocalTime(&time);
AA=birthdate.getAnio();
MM=birthdate.getMes();
DD=birthdate.getDia();
AnioActual=time.wYear;
MesActual=time.wMonth;
DiaActual=time.wDay;
año = AA-AnioActual;
if( MesActual <= MM )
{
Mes = MM - MesActual;
}
else
{
Mes = MM+12-MesActual;
año = año -1;
}
if( DiaActual <= DD )
{
Dia = DD - DiaActual;
}
else
{
Dia=DD+MonthDays[birthdate.esbisiesto(AA)][MM-1]-DiaActual;
Mes = Mes -1;
}
if( Mes < 0 )
{
año = año - 1;
Mes = 12 + Mes;
}
unsigned int Arreglo=año*(-1);
//Result = Format('Años: %.0f, Meses: %.0f, Dias: %.0f', [año, Mes, Dia]);
return Arreglo;
}*/
unsigned int Fecha::CalcularEdad(Fecha birthdate)
{
// Initialize variables
int ReturnAge = 0;
SYSTEMTIME stLocal;
GetLocalTime( &stLocal ); // Get local time
ReturnAge = stLocal.wYear - birthdate.getAnio();
if ( stLocal.wMonth <= birthdate.getMes() )
{
if ( stLocal.wMonth == birthdate.getMes() )
{
if ( stLocal.wDay <= birthdate.getDia() )
ReturnAge--;
}
else
ReturnAge--;
}
return ReturnAge;
}