Im writing a code that, if you input your birthday date and any other date, it returns the total number of years, months and day that you are alive.

Obs.:including (leap) bissextile years.

Obs.2:for invalid dates, the output must be "data invalida" (invalid date in portuguese).

Inputs/Outputs:

Obs.: The date format is in the brazillian standard, the format is Day / Month / Year.


8 //the first input is the number of inputs that you will test.


Input 1: 29/02/2000

Input 2: 01/03/2001

Output: 1 0 1


Input 1: 29/02/2000

Input 2: 28/02/2001

Output: 1 0 0


Input 1: 29/12/2012

Input 2: 13/01/2013

Output: 0 0 15


Input 1: 27/05/2012

Input 2: 27/05/2013

Output: 1 0 0


Input 1: 01/01/2012

Input 2: 05/01/2013

Output: 1 0 4


Input 1: 13/05/1966

Input 2: 05/02/2015

Output: 48 8 23


Input 1: 29/02/2003

Input 2: 4/05/2012

Output: data invalida


Input 1: 14/13/1995

Input 2: 7/8/1996

Output: data invalida


The Code:

#include <iostream>
#include <cstdio>

using namespace std;

int verificar(int ano)
{
if (((ano % 4 == 0) && (ano % 100 != 0)) || (ano % 400 == 0))

    return 1;

else
    return 0;
}
int checkdia(int dia, int mes, int ano){    

if (dia>0)

    if (((mes==1)||(mes==3)||(mes==5)||(mes==7)||(mes==8)||(mes==10)||(mes==12)) && (dia<=31))
            return 1;

    else{

        if (((mes==4)||(mes==6)||(mes==9)||(mes==11)) && (dia<=30))

            return 1;

        else{

            if ((mes==2) && (dia<=28))

                return 1;

            else{

                if ((((verificar(ano))==true)&&(dia<=29))&&(mes==2))

                    return 1;

                else

                    return 0;
            }
        }
    }
else
return 0;
}

int checkmes(int mes)
{
if ((mes>0) && (mes<=12))
    return 1;
else
    return 0;
}

int checkano(int ano)
{
if ((ano>0) && (ano<11000))
    return 1;
else
    return 0;
}

int main(){

int numerodetestes, mes1, mes2, dia1, dia2, ano1, ano2, teste11, teste12, teste13, teste21, teste22, teste23;

cin>>numerodetestes;

for(int c=0;c<=numerodetestes;c++){

    scanf("%d/%d/%d", &dia1, &mes1, &ano1);
    scanf("%d/%d/%d", &dia2, &mes2, &ano2);

    teste11=checkano(ano1);
    teste12=checkdia(dia1,mes1,ano1);
    teste13=checkmes(mes1);
    teste21=checkano(ano2);
    teste22=checkdia(dia2,mes2,ano2);
    teste23=checkmes(mes2);

    if ((dia1==29)&&(mes1==02))
        dia1=28;

    if ((teste11+teste12+teste13+teste21+teste22+teste23)==6){
        total=((365*(ano2-ano1))+sexto);
                    //... incomplete part ...//
    }
    else
        cout<<"data invalida"<<endl;
}
return 0;
}

Glossary:

dia: day

mes: month

ano: year

numerodetestes: number of tests

verificar: function for bissextile

check(...): function to check "X"

teste"XX": int variable that will receive a 0 or 1 of a check function.

THE PROBLEM IS: I cant figure out how to calculate it in an organized way.

有帮助吗?

解决方案

You should use bool instead of int for your return values :

bool verificar(int ano)
{
    return ((ano % 4 == 0) && (ano % 100 != 0)) || (ano % 400 == 0));
}

Also your check functions could be greatly simplified :

bool checkmes(int mes)  {
    return ( (mes > 0) && (mes <= 12) );
}

bool checkano(int ano) {
    return ( (ano > 0) && (ano < 11000) );
}

bool checkdia(int dia, int mes, int ano) {   

    if(dia < 1 || dia > 31) return false;
    if(mes%2 == 0 && dia >30) return false;
    if(mes == 2 && dia >28) return verificar(ano);
    return true;
}

Then you could write something like :

bool checkdata(int dia, int mes, int ano) {
    return ( checkano(ano) && checkmes(mes) && checkdia(dia, mes, ano) );
}

Which would allow you to write :

if( !checkdata(dia1,mes1,ano1) || !checkdata(dia2,mes2,ano2) ) {
    cout<< "data invalida" <<endl;
}

Now for the main problem, you could easily get an estimation of the number of day between two dates, but you can't easily get the real number, because dates are nothing but logical. You would have to take into account all calendar modifications across history.

For an easy estimation, I would first add/subtract the dates offset to the first of January, and then add the year difference :

bool isLeap(int year) {
     return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}

int monthLengths[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int monthLength(int month, int year) {
    int n = monthLengths[month-1];
    if(month == 2 && isLeap(year)) n += 1;
    return n;
}

int yearLength(int year) {
    return isLeap(year) ? 366 : 365;
}


int nDay = 0; /* day counter */
/* subtract data1 offset to 01/01 */
nDay -= dia1;
for(int i = mes1; i > 1; --i) {
    nDay -= monthLength(i - 1, ano1);
}
/* add data2 offset to 01/01 */
nDay += dia2;
for(int i = mes2; i > 1; --i) {
    nDay += monthLength(i - 1, ano2);
}
/* add year offset */
for(int i = ano2; i > ano1; --i) {
    nDay  += yearLength(i);
}

cout << "Difference = " << nDay << " days" << endl;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top