clase FECHA con modificaciones

Iniciado por david_BS, 4 Abril 2012, 23:12 PM

0 Miembros y 1 Visitante están viendo este tema.

david_BS


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;
}