Days between dates.

So I've been struggling with this homework for a long time...
This still does not work and teachers comment was that I have to change the code and add set,get operators...
I tried by myself and it only got worse.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
   #include <iostream>
 #include <cmath>

 using namespace std;

 class date
 {
    private:
    int m;
    int d;
    int y;

    public:
    date(int, int, int);
    int countLeapYears(date&);
    int getDifference(date&);
    int operator-(date&);
  };

   int main()
   {
    int day, month, year;
    char c;

    cout << "Enter a start date: " << endl;
    cin >> month >> c >> day >> c >> year;

    date start = date(month, day, year);

    cout << "Enter an end date: " << endl;
    cin >> month >> c >> day >> c >> year;

    date end = date(month, day, year);
    int duration = end-start;

     cout << "The number of days between those two dates are: " <<
     duration << endl;

     return 0;
   }


    date::date(int a, int b, int c)
    {
    m = a;
    d = b;
    y = c;
    }

    const int monthDays[13] = {0,31,28,31,30,31,30,31,31,31,31,30,31};

   int date::countLeapYears(date& d)
   {
      int years = d.y;
      if (d.m <= 2)
      years--;
      return years / 4 - years / 100 + years / 400;
    }

   int date::getDifference(date& other)
   {

      int n1 = other.y*365 + other.d;

      for (int i=0; i<other.m - 1; i++)
     {
       n1 += monthDays[i];
       n1 += countLeapYears(other);
      }

      return n1;
      }

   int date::operator-(date& d) {
      int difference = getDifference(d);
      return difference;
    }
Last edited on
I don't know about adding getters/setters, but consider (leap years not tried):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <cmath>

using namespace std;

class date
{
private:
	int m {};
	int d {};
	int y {};
	int days {};
	int countLeapYears() const;

public:
	date(int, int, int);
	int getdays() const;
	int operator-(const date&) const;
};

int main()
{
	int day {}, month {}, year {};
	char c {};

	cout << "Enter a start date (m/d/y): ";
	cin >> month >> c >> day >> c >> year;

	const date start(month, day, year);

	cout << "Enter an end date (m/d/y): ";
	cin >> month >> c >> day >> c >> year;

	const date end(month, day, year);
	const int duration {end - start};

	cout << "The number of days between those two dates are: " << duration << '\n';
}

date::date(int a, int b, int c) : m(a), d(b), y(c) {
	static const int monthDays[13] {0, 31, 28, 31, 30, 31, 30, 31, 31, 31, 31, 30, 31};

	days =  {y * 365 + d};

	for (int i = 0; i < m - 1; ++i)
		days += monthDays[i];

        days += countLeapYears();
}

int date::countLeapYears() const
{
	int years {y};

	if (m <= 2)
		--years;

	return years / 4 - years / 100 + years / 400;
}

int date::getdays() const
{
	return days;
}

int date::operator-(const date& d) const {
	return days - d.getdays();
}



Enter a start date (m/d/y): 1/1/2020
Enter an end date (m/d/y): 1/3/2020
The number of days between those two dates are: 2

Last edited on
I think that he's trying to do too much in one swoop. This is a complex problem with many possible scenarios. This is all the help i can offer given the limited amount of time I have.
gl. Also i'm not really sure if getters and setters are necessary either.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int date::countLeapYears(date& d)
{
    int c{ 0 };
 
    for (int i = this->y; i < d.y + 1;i++) {
        if (isLeap(i)) {
            c++;
        }
    }

    if (isLeap(this->y)) {
        if (this->m > 2) {
            c--;
        }
        else if (this->m == 2 && this->d > 28) {
            c--;
        }
        
    }
    if (isLeap(d.y)) {
        if (d.m == 2 && d.d < 29) { c--; }
        else if (d.m < 2) { c--; }
    }
    return c;
}

bool date::isLeap(int year) {
    if (year % 4 == 0 && year % 100 != 0) {
        true;
    }
    else if (year % 4 == 0 && year % 100 == 0 && year % 400 == 0) {
        return true;
    }
}


but the gist is to count either to the day or the end of the year if it spans over years, and count from the begining of the year to the end date. Then add 365 by number of years in between and then add the number of leap years. keep in mind that has to include the begin year and the end year depending on where the start and end date fall. As you can see from what i wrote it takes that into account. Untested like i said no time.
I think you have some typos in your isLeap function.
Lol I knew it never returns false. I really didn't have much time to digest the logic. From my understanding if a year divides evenly into 4 and 100 but not 400 it's not a leap year. If it divides evenly into 4 but not 100 it is a ly aswell as divide evenly into 4, 100 and 400 it is a ly... I could be wrong on that and I think the rules are different in the gregorian calendar... pre 1900 or something...or maybe the days in the month are all the same. Id have to look into it further. I did a problem like this 6+ months ago. I barely remember.
CountLeapYears() should count the leap years in this date. So it shouldn't take a parameter.
1
2
3
4
5
6
7
   int date::countLeapYears()
   {
      int years = y;
      if (m <= 2)
      years--;
      return years / 4 - years / 100 + years / 400;
    }


difference() is a misleading name. It really computes the number of days since some start date. Let's change the name to daysSinceStart(). Also, like countLeapYears(), it should count the days of the current date, rather than taking a parmeter. last of all, you have a bug: line 68 should be outside the loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
    int date::daysSinceStart()
   {

      int n1 = y*365 + d;

      for (int i=0; i<m - 1; i++)
      {
       n1 += monthDays[i];
      }
      n1 += countLeapYears();

      return n1;
      }


To get the difference between two dates, you compute the daysSinceStart() of each date and take the difference.
1
2
3
4
   int date::operator-(date& d) {
      int difference = daysSinceStart() - d.daysSinceStart();
      return difference;
    }


And the class declaration now looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
 class date
 {
    private:
    int m;
    int d;
    int y;

    public:
    date(int, int, int);
     int countLeapYears();
     int daysSinceStart();
    int operator-(date&);
  };


With these changes, it correctly computes the number of days from the end of WWII to today.
$ ./foo
Enter a start date:
9/2/1945
Enter an end date:
2/3/2021
The number of days between those two dates are: 27548


Get/Set methods that will satisfy the prof are mechanical:
1
2
3
4
5
6
     int getm()         { return m; }
     void setm(int val) { m = val; }
     int getd()         { return d; }
     void setd(int val) { d = val; }
     int gety()         { return y; }
     void sety(int val) { y = val; }


There's a big hole in the code regarding bad values. What if someone enters a date of 2/30/2021? or -4/82/777? or 47843/474733433/-83373333? Your code will happily accept any of these. Does the assignment ask for error checking? Do you think the prof expects it?
Topic archived. No new replies allowed.