0

Hi everyone,
I am having a little trouble finishing my programming assignment. I am trying to write a program that inputs two dates and validates them to make sure the input is ok and that the dates are between 1/1/1850 and 12/31/2100. I have gotten all of the validation down and I have written some functions that validate the date and find out if the date is a leap year. The problem I am having is the calcDays() function. It is supposed to take one of the dates and return the amount of days between the given date and 1/1/1850. I am really lost on how to do this. Any help I can get would be greatly appreciated. I have posted the code that I have so far below. Thanks in advance
Nick

#include <iostream>
using namespace std;
void getDate(int &month, char &first, int &day, char &second, int &year);
bool validDate(int month, char first, int day, char second, int year);
int calcDays(int month, int day, int year);
bool isLeapYear(int year);
int main ()
{
   int yeara, yearb, montha, monthb, daya, dayb;
   char first, second;

   do
   {
       cout << "Enter first date (yyyy-mm-dd): ";
       getDate(montha, first, daya, second, yeara);
   }
   while(!validDate(montha, first, daya, second, yeara));

   do
   {
       cout << "Enter second date (yyyy-mm-dd): ";
       getDate(monthb, first, dayb, second, yearb);
   }
   while(!validDate(monthb, first, dayb, second, yearb));

   cout << "DBD:";
   cout << calcDays(montha, daya, yeara) - calcDays(monthb, dayb, yearb);
   cout << endl;

   return 0;
}


void getDate(int &month, char &first, int &day, char &second, int &year)
{
   cin >> year >> first >> month >> second >> day;
}


bool validDate(int month, char first, int day, char second, int year)
{
  bool date = true;
  int numDays = 0;

  if (month < 1 || month > 12)
  {
      cout << "Bad month:" << month << endl;
      date = false;
  }

  switch (month)
  {
      case 1: case 3: case 5: case 7: case 8: case 10: case 12:
          numDays = 31;
          break;
      case 9: case 4: case 6: case 11:
          numDays = 30;
          break;
      case 2:
          numDays = 28;
          break;
  }

  if(month == 2 && isLeapYear(year))
      numDays++;

  if (day > numDays || day < 1)
  {
      cout << "Bad day for " << month << '/' << year << ':' << day << endl;
      date = false;
  }

  if (year < 1850 || year > 2150)
  {
      cout << "Bad year: " << year << endl;
      date = false;
  }

  if (first !='-' || second !='-')
  {
      cout << "Use only dash \'-\': " << first << ":" << second << endl;
      date = false;
  }

  return date;

}


int calcDays(int month, int day, int year)
{
   // HERE IS WHERE I NEED HELP!

}

bool isLeapYear(int year)
{
   bool leapyear = false;

   if (year % 4 == 0)
       leapyear = true;
   if (year % 100 == 0)
       leapyear = false;
   if (year % 400 == 0)
       leapyear = true;
   return leapyear;
}
2
Contributors
9
Replies
10
Views
12 Years
Discussion Span
Last Post by stupidenator
0

I have been working on it... it doesn't seem to work too well though... I have posted the code below.
Nick

int calcDays(int month, int day, int year)
{
   int m = 1;
   int y = 1850;
   int dbd = 0;
   int dd = 0;
   int numDays = 0;

   dbd = year - y;

   for (int i = 1850; i<dbd; i++)
   {
       dd += 365;

       if (isLeapYear(i))
           dd++;
   }

   while (m < month)
   {
       for (int i=1; i<month; i++)
       {
           switch (i)
           {
               case 1: case 3: case 5: case 7: case 8: case 10: case 12:
                   numDays = 31;
                   break;
               case 9: case 4: case 6: case 11:
                   numDays = 30;
                   break;
               case 2:
                   numDays = 28;
                   break;
           }
           dd += numDays;
           m++;
       }

   }

   dd += day;

   return dd;

}
0

dbd should be year-1, not year-1850.

for the days in current year, you need to use a table that will contain the cumulative number of days from 1 Jan to the end of the previous month. Using a table for this saves a lot of time because loops are expensive. For example

static short MonthDays[13] =
	{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};

So if current date is 15 March, the number of days from 1 Jan to (but not including) 1 March is MonthDays[2] (where Jan = 1, Feb = 2 ...), or 59. If this year is a leap year then add one.

Finally, just add to the previous total the day of the current month.

0

Thanks for the reply. I'm not sure if I will be able to use it like that. The function calcDays() is supposed to return the number of days between the entered date, and january 1, 1850. I also am not able to use an array. I know exactly how to use them, but this is an intro class and he doesn't want us to get ahead. Thanks for your help!
Nick

0

Ok, forget the array stuff. Just fix the other problems.

the first problem with your last post is setting the dbd to the wrong value.

dbd = year - 1;

   for (int i = 1850; i<dbd; i++)
   {
       dd += 365;

       if (isLeapYear(i))
           dd++;
   }

then when calculating the number of days in a month, you need to increment the number of days when current year is a leap year. Also, it doesn't need that while statement around the loop or the m counter. This will cause the program to sum up the number of days multiple times (If it's December, it will sum up the days 12 * 11 times!).

case 2:
                   numDays = 28;
                   if( isLeapYear(year) )
                      numDays++;
                   break;
0

OK, after taking your advice, I made some revisions to the program. Sometimes it will give me the right answer... sometimes it will be a little off.. and for some, it will give me a negative number! I don't really know what's happening here. I am posting my new code with the revisions I have made. Thank you for your help
Nick

#include <iostream>
using namespace std;
void getDate(int &month, char &first, int &day, char &second, int &year);
bool validDate(int month, char first, int day, char second, int year);
int calcDays(int month, int day, int year);
bool isLeapYear(int year);
int main ()
{
   int yeara, yearb, montha, monthb, daya, dayb;
   char first, second;

   do
   {
       cout << "Enter first date (yyyy-mm-dd): ";
       getDate(montha, first, daya, second, yeara);
   }
   while(!validDate(montha, first, daya, second, yeara));

   do
   {
       cout << "Enter second date (yyyy-mm-dd): ";
       getDate(monthb, first, dayb, second, yearb);
   }
   while(!validDate(monthb, first, dayb, second, yearb));

   cout << "DBD:";

   
// I thought this was where I was getting the negative number from,
// so i put the 'if' statements around it but that still seems to fail.
if (yeara >= yearb)
       cout << (calcDays(montha,daya,yeara)) - (calcDays(monthb,dayb,yearb));
   else
       cout << (calcDays(monthb,dayb,yearb)) - (calcDays(montha,daya,yeara));
   cout << endl;

   return 0;
}


void getDate(int &month, char &first, int &day, char &second, int &year)
{
   cin >> year >> first >> month >> second >> day;
}


bool validDate(int month, char first, int day, char second, int year)
{
   bool date = true;
   int numDays = 0;

   if (month < 1 || month > 12)
   {
       cout << "Bad month:" << month << endl;
       date = false;
   }

   switch (month)
   {
       case 1: case 3: case 5: case 7: case 8: case 10: case 12:
           numDays = 31;
           break;
       case 9: case 4: case 6: case 11:
           numDays = 30;
           break;
       case 2:
           numDays = 28;
           break;
   }

   if(month == 2 && isLeapYear(year))
       numDays++;

   if (day > numDays || day < 1)
   {
       cout << "Bad day for " << month << '/' << year << ':' << day << endl;
       date = false;
   }

   if (year < 1850 || year > 2150)
   {
       cout << "Bad year: " << year << endl;
       date = false;
   }

   if (first !='-' || second !='-')
   {
       cout << "Use only dash \'-\': " << first << ":" << second << endl;
       date = false;
   }

   return date;

}


int calcDays(int month, int day, int year)
{
   int y = year-1;
   int m = month-1;
   int numDays = 0;

   for(int i=1850; i<y; i++)
   {
       numDays += 365;

       if (isLeapYear(i))
           numDays++;
   }

   for (int i=1; i<m; i++)
   {
       switch (i)
       {
           case 1: case 3: case 5: case 7: case 8: case 10: case 12:
               numDays += 31;
               break;
           case 9: case 4: case 6: case 11:
               numDays += 30;
               break;
           case 2:
               numDays += 28;
               if (isLeapYear(year))
                   numDays++;
               break;
       }
   }

   numDays += day;

   cout << numDays << endl;

   return numDays;
}

bool isLeapYear(int year)
{
   bool leapyear = false;

   if (year % 4 == 0)
       leapyear = true;
   if (year % 100 == 0)
       leapyear = false;
   if (year % 400 == 0)
       leapyear = true;
   return leapyear;
}
0
int calcDays(int month, int day, int year)
{
	int i;
   int numDays = 0;

   for(i=1850; i<year; i++)
   {
       numDays += 365;

       if (isLeapYear(i))
           numDays++;
   }

   for (i=1; i<month; i++)
   {
       switch (i)
       {
           case 1: case 3: case 5: case 7: case 8: case 10: case 12:
               numDays += 31;
               break;
           case 9: case 4: case 6: case 11:
               numDays += 30;
               break;
           case 2:
               numDays += 28;
               if (isLeapYear(year))
                   numDays++;
               break;
       }
   }

   numDays += (day-1); // excludes the current day

   cout << numDays << endl;

   return numDays;
}

and use absolute value of the two days because the first value may indeed be less than the second, such as if the first date entered is 1850-01-01 the calculation is 0.

// I thought this was where I was getting the negative number from,
// so i put the 'if' statements around it but that still seems to fail.
   int days = calcDays(montha,daya,yeara) - calcDays(monthb,dayb,yearb);
   days = abs(days);
   cout << days << endl;
0

I made the adjustments that you provided. It was coming up ok on a couple of the samples that i ran. But on other ones, it would come up either 30 or 28 days short. I made an adjustment by adding an '=' sign in the for (int i=1; i<=m; i++) right before the switch statement. That corrected the 30 or 28 behind problem, but now on the ones that were like that, it is 1 over and I can't seem to find where the extra 1 is being added on. Any way you could help me track this? I have included below the revised calcDays() function and the sample material. Thank you very much for your help.
Nick

int calcDays(int month, int day, int year)
{
   int y = year-1;
   int m = month-1;
   int numDays = 0;

   for(int i=1850; i<y; i++)
   {
       numDays += 365;

       if (isLeapYear(i))
           numDays++;
   }

   for (int i=1; i<=m; i++)
   {
       switch (i)
       {
           case 1: case 3: case 5: case 7: case 8: case 10: case 12:
               numDays += 31;
               break;
           case 9: case 4: case 6: case 11:
               numDays += 30;
               break;
           case 2:
               numDays += 28;
               if (isLeapYear(year)) // checked
                   numDays++;
               break;
       }
   }

   numDays += (day-1);

//    cout << numDays << endl;

   return numDays;
}

SAMPLE PROGRAM RUNS (user input is underlined)

Enter first date (yyyy-mm-dd): 2005-10-11
Enter second date (yyyy-mm-dd): 2005-10-11
DBD:0 // this one is correct.

Enter first date (yyyy-mm-dd): 2000-1-1
Enter second date (yyyy-mm-dd): 2000-2-29
DBD:59 // should actually be 58

Enter first date (yyyy-mm-dd): 2000-3-1
Enter second date (yyyy-mm-dd): 2000-1-1
DBD:60 // should actually be 59

Enter first date (yyyy-mm-dd): 1982-7-23
Enter second date (yyyy-mm-dd): 2005-10-11
DBD:8480 // this one is correct

Enter first date (yyyy-mm-dd): 2005-10-11
Enter second date (yyyy-mm-dd): 1982-7-23
DBD:8480 // this one is correct

Enter first date (yyyy-mm-dd): 2005-2-28
Enter second date (yyyy-mm-dd): 2005-1-5
DBD:54 // should actually be 53

Thank you for your help!

0

where are 26 days between 5 and 31 Jan (31-5=26). 26 in Jan + 28 days in Feb = 54.


There are 60 days between 1 Jan 2000 and 1 March 2000 -- year 2000 was a leap year.

0

Thanks a lot for your help. I got the program working and got it submitted. I really appreciate you helping me with that.
Nick

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.