Operator Function within a class to subtract 2 dates

Hello,

I have to subtract 2 dates from each other in long int form and then I have to display the new date. Unfortunately, when I do so I get a ridiculous number for the month!

Could someone see where there maybe an error?

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
  #include <iostream>
#include <iomanip>
using namespace std;
// class declaration section
class Date
{
private:
    int month, day, year;
public:
    Date(int = 7, int = 4, int = 2005); // constructor
    Date(long); // type conversion constructor
    Date operator+(int); // overload the + operator
    Date operator-(int);
    void showDate();
};

// class implementation section
// constructor
Date::Date(int mm, int dd, int yyyy)
{
month = mm;
day = dd;
year = yyyy;
}

// type conversion constructor from long to Date
Date::Date(long findate)
{
    year = int(findate/10000.0);
    month = int((findate - year * 10000.0)/100.0);
    day = int(findate - year * 10000.0 - month * 100.0);
}

Date Date::operator+(int days)
{
    Date temp; // a temporary date to store the result
    temp.day = day + days; // add the days
    temp.month = month;
    temp.year = year;

    while (temp.day > 30) // now adjust the months
    {
        temp.month++;
        temp.day -= 30;
    }

    while (temp.month > 12) // adjust the years
    {
        temp.year++;
        temp.month -= 12;
    }

return temp; // the values in temp are returned
}

Date Date::operator-(int days)
{
    Date temp; // a temporary date to store the result
    temp.day = day - days; // subtract the days
    temp.month = month;
    temp.year = year;

    while (temp.day > 30) // now adjust the months
    {
        temp.month++;
        temp.day -= 30;
    }

    while (temp.month > 12) // adjust the years
    {
        temp.year++;
        temp.month -= 12;
    }

return temp; // the values in temp are returned
}
// member function to display a date
void Date::showDate()
{
    cout << setfill('0')
        << setw(2) << month << '/'
        << setw(2) << day << '/'
        << setw(2) << year % 100;

    return;
}

int main()
{
    Date a, b(20061225L), c(4,1,2007); // declare 3 objects and
// initialize 2 of them

    cout << "Dates a, b, and c are ";
    a.showDate();

    cout << ", ";
    b.showDate();

    cout << ", and ";
    c.showDate();

    cout << ".\n";
    a = Date(20080103L); // cast a long to a Date

    cout << "Date a is now ";
    a.showDate();

    cout << "The initial date is ";
    a.showDate();

    cout << endl;
    b = a + 284; // add in 284 days = 9 months and 14 days

    cout << "The new date is ";
    b.showDate();

    cout << endl;

    cout << ".\n";
    a = Date(20080103L); // cast a long to a Date

    cout << "Date a is now ";
    a.showDate();

    cout << "The initial date is ";
    a.showDate();

    cout << endl;
    b = a - 284; // add in 284 days = 9 months and 14 days

    cout << "The new date is ";
    b.showDate();

    cout << endl;

    cout << ".\n";

return 0;
}
In your overloaded operator-() you perform nearly the same calculation than in the overloaded operator+()...
Maybe you want it to be more similar to this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Date Date::operator-(int days)
{
    Date temp; // a temporary date to store the result
    temp.day = day - days; // subtract the days
    temp.month = month;
    temp.year = year;

    while (temp.day < 1) // now adjust the months
    {
        temp.month--;
        temp.day += 30;
    }

    while (temp.month < 1) // adjust the years
    {
        temp.year--;
        temp.month += 12;
    }

return temp; // the values in temp are returned
}


To be honest, I haven't check the result if it's correct, but I'm quite sure it isn't: you don't consider neither 31 days long months nor February, let alone leap years...
Last edited on
Set up the Date class as a wrapper around std::chrono::system_clock::time_point so that you can use the in-build standard library time and date facilities to overload the operators instead of trying to rebuild from scratch:
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
# include <iostream>
# include <chrono>
# include <ctime>
# include <string>

struct Date
{
    int m_year;
    int m_month;
    int m_day;
    std::chrono::system_clock::time_point m_timePoint;

    Date(int year, int month, int day)
    {
        struct std::tm t;
        t.tm_sec = 0;        // second of minute (0 .. 59 and 60 for leap seconds)
        t.tm_min = 0;        // minute of hour (0 .. 59)
        t.tm_hour = 0;      // hour of day (0 .. 23)
        t.tm_mday = day;       // day of month (1 .. 31)
        t.tm_mon = month-1;      // month of year (0 .. 11)
        t.tm_year = year-1900; // year since 1900
        t.tm_isdst = -1;       // determine whether daylight saving time
        std::time_t tt = std::mktime(&t);
        if (tt == -1)
        {
            throw "no valid system time";
        }
        m_timePoint = std::chrono::system_clock::from_time_t(tt);
    }
    std::chrono::system_clock::time_point operator + (const Date& rhs)
    //returns the greater timepoint + duration b/w the 2 timepoints
    {
        return ((m_timePoint >= rhs.m_timePoint) ?
                    m_timePoint + (m_timePoint - rhs.m_timePoint)
                    : rhs.m_timePoint + (rhs.m_timePoint - m_timePoint));
    }
    double operator - (const Date& rhs)
    //returns absolute duration in hours, can also extend to days, minutes on similar lines
    {
        return((m_timePoint >= rhs.m_timePoint) ?
            std::chrono::duration_cast<std::chrono::hours>(m_timePoint - rhs.m_timePoint).count()
            : std::chrono::duration_cast<std::chrono::hours>(rhs.m_timePoint - m_timePoint).count());
    }
};
inline
std::string asString (const std::chrono::system_clock::time_point& tp)
{
    // convert to system time:
    std::time_t t = std::chrono::system_clock::to_time_t(tp);
    std::string ts = ctime(&t);
    // convert to calendar time, taking local time zone into a/c
    //std::string ts = asctime(gmtime(&t));
    //// convert to calendar time, using universal time UTC
    ts.resize(ts.size()-1);        // skip trailing newline
    return ts;
}

int main()
{
    Date d(2017, 5, 20);
    std::cout << asString((d + Date(2017, 6, 11))) << "\n";

    auto diff = d - Date(2017, 6, 11);
    std::cout << diff << " hours \n";
}

you can look up any unknown functions individually but for a comprehensive treatment of clocks and timers see 'The C++ Standard Library' (2nd ed), Nicolai Josuttis, section 5.7
Last edited on
Hello Enoizat!

Thanks very much, I actually tried that, but must've missed something along the way. Works a treat.

Gunnerfunner, I'm just working through some exercises in a textbook from one of my old University courses. I'm not aware of one of that library. So I'll have to look it up. I do usually use standard libraries where I can. No point in re-inventing the wheel, just use someone else's.
Topic archived. No new replies allowed.