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

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;

}

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.

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

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;

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

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!

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.

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 article has been dead for over six months. Start a new discussion instead.