Overloading the '-' operator - c++

Currently I'm writing a program that has a section to determine the difference in days between two dates, but by overloading the minus operator.
I'm currently staring at my screen drawing a complete blank. I have some fleeting thoughts in my head but they are exactly that, fleeting.
What's to happen in the main.cpp is that there are going to be two variables, for instance beethovenDeathDate and beethovenBirthDate that will be subtracted to determine how long he lived for. Which is something around 22000 days if I recall correctly.
So without further ado, here is my code:
Date.cpp
const std::string Date::MONTH_STRINGS[] =
{
"", //one based indexing
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
const int Date::DAYS_PER_MONTH[] =
{
0, //one based indexing
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
Date::Date(int day, int month, int year) : _year(year), _month(month), _day(day)
{
isValid();
}
Date::Date()
{
time_t t = time(0); // get time now
struct tm * now = localtime( & t );
_year = now -> tm_year + 1900;
_month = now -> tm_mon + 1;
_day = now -> tm_mday;
}
int Date::maxDay(int month, int year)
{
int ret = DAYS_PER_MONTH[month];
if(isLeapYear(year) == true && month == 2)
{
++ret;
}
return ret;
}
void Date::addDay(bool forward)
{
if(forward)
{
if(_day < maxDay(_month, _year))
{
++_day;
}
else
{
_day = MIN_DAY;
++_month;
if(_month > MAX_MONTH)
{
_month = MIN_MONTH;
++_year;
}
}
}
else
{
if(_day <= MIN_DAY)
{
--_month;
if(_month < MIN_MONTH)
{
_month = MAX_MONTH;
--_year;
}
_day = maxDay(_month, _year);
}
else
{
--_day;
}
}
}
std::string Date::toString() const
{
if(isValid() == false)
{
return std::string();
}
std::stringstream ss;
ss << MONTH_STRINGS[_month] << " " << _day << ", " << _year;
return ss.str();
}
bool Date::isValid() const
{
if(_month < MIN_MONTH || _month > MAX_MONTH)
{
std::cerr << "Invalid date " << std::endl;
return false;
}
int daysThisMonth = maxDay(_month, _year);
if(_day < MIN_DAY || _day > daysThisMonth)
{
std::cerr << "Invalid date " << std::endl;
return false;
}
return true;
}
bool Date::isLeapYear(int year)
{
if(!(year % 4))
{
if(!(year % 100))
{
if(!(year % 400))
{
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
else
{
return false;
}
}
bool Date::isLeapYear() const
{
return isLeapYear(_year);
}
bool Date::isLeapDay() const
{
return isLeapDay(_day, _month, _year);
}
bool Date::isLeapDay(int day, int month, int year)
{
if(day == 29 && month == 2 && isLeapYear(year) == true)
{
return true;
}
else
{
return false;
}
}
void Date::addYears(int years)
{
if(years == 0)
{
return;
}
if(isLeapDay() && !isLeapDay(_day, _month, _year + years))
{
_day = Date::DAYS_PER_MONTH[_month];
}
_year += years;
}
void Date::addMonths(int months)
{
if(months == 0)
{
return;
}
int deltayears = months / MAX_MONTH;
int deltamonths = months % MAX_MONTH;
int newMonth = 0;
if(months > 0)
{
newMonth = (_month + deltamonths) % MAX_MONTH;
if((_month + deltamonths) > MAX_MONTH)
{
++deltayears;
}
}
else
{
if((_month + deltamonths) < MIN_MONTH)
{
--deltayears;
newMonth = _month + deltamonths + MAX_MONTH;
}
else
{
newMonth = _month + deltamonths;
}
}
if(_day > maxDay(newMonth, _year + deltayears))
{
_day = maxDay(newMonth, _year + deltayears);
}
_year += deltayears;
_month = newMonth;
}
void Date::addDays(int days)
{
if(days == 0)
{
return;
}
if(days < 0)
{
for(int i = 0; i > days; --i)
{
addDay(false);
}
return;
}
for(int i = 0; i < days; ++i)
{
addDay(true);
}
}
std::ostream& operator<<(std::ostream& os, const Date& date)
{
os << date.toString();
return os;
}
Date Date::operator+(int days) const
{
Date ret = *this;
ret.addDays(days);
return ret;
}
Date& Date::operator+=(int days)
{
addDays(days);
return *this;
}
//This is where I get stumped (the parameters was just one of my failed experiments
Date& Date::operator-(int day, int month, int year)
{
}

The function can be written either as a member, or as a free function. The member function signature would look like this:
TimeDuration Date::operator-(Date const & rhs) const
The free function would look like this:
TimeDuration operator-(Date const & lhs, Date const & rhs)
TimeDuration here is a completely seperate type representing a length of time. If you want, you could just make it an int signifying the number of days, but it would be better, in my opinion, to have a more expressive type for this purpose. Whatever you decide regarding the return type, it doesn't make any sense for the type to be Date (and certainly not Date&).
A possible (albeit not incredibly efficient) implementation, given that you've already written a function to add a day to a date, would be something like this:
if lhs_date comes before rhs_date
add days to (a copy of) lhs_date until lhs_date == rhs_date
return the negative of number of days added
if rhs_date comes before lhs_date
add days to (a copy of) rhs_date until rhs_date == lhs_date
return the number of days added
else
return 0
Another function you might want (or maybe this is what you actually wanted originally, but your wording doesn't indicate it) is a function which can subtract a length of time from a Date. In that case, the return value would be another Date object (but not Date&), and the possible signatures would look something like this:
Date Date::operator-(TimeDuration rhs) const // member version
Date operator-(Date const & lhs, TimeDuration const & rhs) // non-member version

You should do this:
//This is where I get stumped (the parameters was just one of my failed experiments
TimeDuration& Date::operator-(Date const & d1)
{
// ... processing ...
// this - d1;
}
and call it as:
Date d1 = new Date(20, 01, 2013);
TimeDuration duration = d1 - (new const Date(20, 01, 1922));
// Calculate no. of days or years using duration
The logic is as follows:
Pass two Date objects (first could be implicit) to the overloading function and return TimeDuration
To invoke this operator, you may create a Date object with the data that you have, instead of passing each value separately.
Please check for exact syntax.

Related

Comparing data in array of objects using a member boolean function

First I need to compare the date of births in the array with the operator== function which is in the class Person, and also show the person with the earliest date of birth with the operator< function which is also in class Person. But I have trouble understanding what I'm doing wrong.
I was thinking of showing the earliest date of birth operator< using the same way as I did with operator== but now that it doesn't work, I have no idea.
#include <iostream>
#include <string>
using namespace std;
class Birth_date
{
private:
unsigned int day{};
unsigned int month{};
unsigned int year{};
public:
Birth_date() {}
Birth_date(int day, int month, int year)
{
this->day = day;
this->month = month;
this->year = year;
}
Birth_date(const Birth_date& birth)
{
day = birth.day;
month = birth.month;
year = birth.year;
}
void set_day(int day)
{
this->day = day;
}
void set_month(int month)
{
this->month = month;
}
void set_year(int year)
{
this->year = year;
}
int get_day()
{
return day;
}
int get_month()
{
return month;
}
int get_year()
{
return year;
}
friend bool operator == (const Birth_date& a, const Birth_date& b)
{
return (a == b);
}
bool operator < (const Birth_date& bd)
{
return day < bd.day && month < bd.month && year < bd.year;
}
bool operator > (const Birth_date& bd)
{
return day > bd.day && month > bd.month && year > bd.year;
}
ostream& Output(ostream& out)
{
out << "Date of birth: " << day << "/" << month << "/" << year << endl;
return out;
}
};
class Person
{
private:
string name;
Birth_date dob;
public:
Person() {}
Person(string name, Birth_date dob)
{
this->name = name;
this->dob = dob;
}
Person(const Person& p)
{
name = p.name;
dob = p.dob;
}
string get_name()
{
return name;
}
Birth_date get_dob()
{
return dob;
}
bool operator < (const Person& p)const
{
Birth_date bd1 = p.dob;
Birth_date bd2 = p.dob;
return (bd1 < bd2);
}
bool operator == (const Person& p)const
{
return (dob == p.dob);
}
const ostream& output(ostream& out)
{
out << "Name: " << name << "\t" ;
dob.Output(out);
return out;
}
};
int main()
{
Person students[5] = { Person("Ivan Petkov",Birth_date(10,6,1999)),
Person("Gabe Trent",Birth_date(20,12,1996)),
Person("Maggy Sommer",Birth_date(5,2,2000)),
Person("Cameron Dallas",Birth_date(1,4,2001)),
Person("Catherine Crumb",Birth_date(28,8,2000)) };
for (int i = 0; i < 5; i++)
{
students[i].output(cout);
}
cout << "\n";
for (int i = 0; i < 5; i++)
{
for (int x = i + 1; x < 5; x++)
{
if (students[i].operator==(students[x]))
{
cout << "Students " << students[i].get_name()
<< "and " << students[x].get_name()
<< "have the same date of birth." << endl;
}
else
cout << "Nobody has the same date of birth." << endl;
}
}
return 0;
}
Right now the only output is the array and then the program just exits.
When you're comparing dates there's the possibility that the year and the month are the same but the day is different.
21/4/2003 > 20/4/2003
however in your code you check that the month and year are greater and can't be equal.
return day < bd.day && month < bd.month && year < bd.year;
by your code if the dates are: 29/1/2000 and 1/3/2000 it would return false.
your functions should first check if the years are not the same, if they are then you next check the months and then the days.
Here's an example of a code I once wrote:
bool MyDate::operator >(const MyDate& d)const {
if (year < d.year)
return false;
else if (year > d.year)
return true;
else if (year == d.year) {
if (month < d.month)
return false;
else if (month > d.month)
return true;
if (month == d.month) {
if (day < d.day)
return false;
else if (day > d.day)
return true;
else
return false;
}
}
return true;
}

How can I optimize compare function for custom date structure?

I want to sort a vector of dates and I wrote compare function for it:
#include <iostream>
struct date {
int day;
int month;
int year;
};
int compare_dates(date a, date b) {
if (a.year < b.year) {
return -1;
} else if (a.year == b.year) {
if (a.month < b.month) {
return -1;
} else if (a.month == b.month) {
if (a.day < b.day) {
return -1;
} else if (a.day > b.day) {
return 1;
}
} else {
return 1;
}
} else {
return 1;
}
return 0;
}
int main() {
date a = {};
date a.day = 19;
date a.month = 11;
date a.year = 2016;
date b = {};
date b.day = 20;
date b.month = 11;
date b.year = 2016;
compare_dates(a, b) // -1
compare_dates(b, a) // 1
compare_dates(b, b) // 0
return 0;
}
It is working well, but compare_dates function looks awful. Is there any idea how can I improve it?
I'm not a C++ expert and the others are pointing out that std::sort() doesn't require three-way comparison, only a <. But to clean up your code as written:
Your compare_dates() keeps doing three-way comparisons for >/</==, and wants a +1/-1/0 return value. So declare a three-way cmp() helper function which does that, like we do in Python. Now your code reduces to:
int cmp(int x, int y) {
return (x>y) ? 1 : ((x<y) ? -1 : 0);
}
int compare_dates(date a, date b) {
if (cmp(a.year, b.year) != 0)
return cmp(a.year, b.year);
if (cmp(a.month, b.month) != 0)
return cmp(a.month, b.month);
return cmp(a.day, b.day);
}
You only fall-through into doing the lower-order comparisons if the higher-order comparison gave '=='. So that allows you to avoid all the else-clauses, braces and indenting, which keeps your indent level constant and is easy on the eyes. It also calls out the symmetry of the computations.
This will be enough for sorting a containers of dates into ascending order:
bool compareDates(date const& lhs, date const& rhs) const {
if(lhs.year == rhs.year) {
if(lhs.month == rhs.month) {
return lhs.day < rhs.day;
}
return lhs.month < rhs.month;
}
return lhs.year < rhs.year;
}
// sort(dates, dates + n, compareDates);
Edit
I intentionally didn't handle -1 separately as for overriding comparator of STL containers like std::sort(), priority_queue or std::set we don't need to provide integer return code and make to code relatively complex. Boolean is enough.
What about using the fact that a day use only 4 bit and a month only 5?
#include <iostream>
struct date
{
int day;
int month;
int year;
};
int compare_dates (date a, date b)
{
long da { (a.year << 9) + (a.month << 4) + a.day };
long db { (b.year << 9) + (b.month << 4) + b.day };
return da < db ? -1 : (da > db);
}
int main()
{
date a = { 19, 11, 2016 };
date b = { 20, 11, 2016 };
std::cout << compare_dates(a, b) << std::endl; // print -1
std::cout << compare_dates(b, a) << std::endl; // print 1
std::cout << compare_dates(b, b) << std::endl; // print 0
return 0;
}
--- EDIT ---
As pointed by Christian Hackl, this code is a little obscure.
I hope that can be more comprensible if you translate the bitfield part in the date struct, trasforming it in a union.
So you can initialize separate year, month and day components and use a full component for compares.
Something as follows
#include <iostream>
union date
{
struct
{
unsigned long day : 5U;
unsigned long month : 4U;
unsigned long year : 23U;
} s ;
unsigned long full;
};
int compare_dates (date const & a, date const & b)
{ return a.full < b.full ? -1 : (a.full > b.full); }
int main()
{
date a = { { 19, 11, 2016 } };
date b = { { 20, 11, 2016 } };
std::cout << compare_dates(a, b) << std::endl; // print -1
std::cout << compare_dates(b, a) << std::endl; // print 1
std::cout << compare_dates(b, b) << std::endl; // print 0
return 0;
}

Incrementing dates in a loop

This is an exercise; I'm forbidden to use built-in date function of C++ or any readily available library.
I have this code:
#include <iostream>
#include <vector>
using namespace std;
bool IsLeap(unsigned int year)
{
if (year % 4 != 0) return false;
else
if (year % 100 != 0) return true;
else
if (year % 400 != 0) return false;
else
return true;
}
class Date
{
public:
unsigned short int Day;
unsigned short int Month;
unsigned short int Year;
unsigned short int DayOfWeek;
};
int MonthLimit(int Month, int year)
{
switch (Month)
{
case 4:
case 6:
case 9:
case 11:
{
return 30;
break;
}
case 1:
case 3:
case 5:
case 7:
case 8:
case 12:
{
return 31;
break;
}
case 2:
if (IsLeap(year))
{
return 29;
break;
}
else
{
return 28;
break;
}
}
}
const Date FirstDayEver = { 1, 1, 1900, 1 }; //January 1, 1900 was on a Monday.
int main()
{
unsigned int years;
cin >> years;
vector<int> counters(7); //whenever a 13th falls on a day X, we increment the Xth counter. It's that simple
for (Date i = FirstDayEver; !((i.Day == 31) && (i.Month == 12) && (i.Year == 1900 + years - 1)); i.Day++)
{
i.DayOfWeek = (i.DayOfWeek + 1) % 7;
if (i.Month == MonthLimit(i.Month, i.Year))
{
i.Month++;
i.Day = 1;
cout << "Proceeded to " << i.Day << "." << i.Month << "." << i.Year << "\n";
}
if ((i.Day == 31) && (i.Month == 12))
{
i.Year++;
i.Day = 1;
i.Month = 1;
cout << "Proceeded to " << i.Day << "." << i.Month << "." << i.Year << "\n";
}
if (i.Day == 13)
{
counters[i.DayOfWeek]++;
cout << i.Day << "." << i.Month << "." << i.Year << " was a " << i.DayOfWeek << "\n";
}
}
cout << counters[6] << " " << counters[7] << " " << counters[1] << " " << counters[2] << " " << counters[3] << " " << counters[4] << " " << counters[5] << "\n";
exit(0);
}
The debug info (couts) is there to see whether anything happens in the loop.
So far the only thing that happens is a lot of lines saying "13.1.1900 was a " varying number.
I think the desired logic of incrementing a date is rather clear from the code, but I'm trying to increment something wrong.
Where's my mistake?
You're complicating your increment procedure too much.
I'm actually still trying to work out exactly how it all fits together (edge cases etc) but it seems that you tried to do each day/month/year independantly.
You can do all your incrementing in a simple function like this:
void increment_Date(Date &d)
{
d.DayOfWeek = (d.DayOfWeek + 1) % 7; //increase weekday
if (++d.Day > MonthLimit(d.Month, d.Year)//increase day, if larger than month size...
{
d.Day = 1; //reset day to 1
if (++d.Month > 12) //increase month, if larger than year size
{
d.Month = 1; //reset month to 1
d.Year++; //increase year
}
}
}
The logic is simpler because I approached it in a slightly different way than you seem to have done.
In the function above, I increase the smallest unit first (day), check for overflow and then move up to month if needed (and so on).
This works in the same way that a car's mileage dial's digits only tick up when the dial reaches 10 and goes back to 0. Or, adding 1 to 9 and 'overflowing' into the 10's digit of a number.
Otherwise your code is good. The Switch statement for MonthLimit was a good choice.
I'd add a switch statement in a function to return a string for day of week:
std::String printable_DOW(int DOW)
{
switch (DOW)
case 0:
return "Sunday";
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday";
}
and a print_date function too:
void print_date(Date d)
{
std::cout<< printable_DOW(d.DayOfWeek)
<< ", " << d.Day << "." << d.Month << "." d.Year;
}
and it's pretty easy to put it all together and use too:
int main
{
Date my_date;
my_date.Day = 1;
my_date.Month = 1;
my_date.Year = 2000;
my_date.DayOfWeek = 0; //assuming 0 == Sunday, 1 = Monday...
for (int daycount = 0; daycount < 5114 /*days since 1/1/2000 to today*/; daycount++)
{
increment_date(my_date);
//debug:
print_date(my_date);
}
//print "today's" date:
print_date(my_date);
}
As a class:
It's mostly here and (mostly) works. Feel free to edit people!
class date
{
private:
unsigned short int day;
unsigned short int month;
unsigned short int year;
unsigned short int day_of_week;
int month_limit();
bool is_leap_year();
public:
date();
date(int in_day, int in_month, int in_year, int in_day_of_week);
date& date::operator=(date rhs)
date& operator++(); //pre-increment (++date)
date operator++(int); //post-increment (date++)
//these are "special" they don't work exactly as you might think and are slightly broken right now,
//but I'm putting them in regardless
//they also don't work on DOW right now.
date& operator+=(const date& rhs)
date& operator-=(const date& rhs)
inline date operator+(date lhs, const date& rhs)
inline date operator-(date lhs, const date& rhs)
}
//phwew
date::date(int in_day, int in_month, int in_year, int in_day_of_week)
{
this->day = in_day;
this->month = in_month;
this->year = in_year;
this->day_of_week = in_doay_of_week;
}
date::month_limit()
{
switch (this->month)
{
case 4:
case 6:
case 9:
case 11:
{
return 30;
break;
}
case 1:
case 3:
case 5:
case 7:
case 8:
case 12:
{
return 31;
break;
}
case 2:
if (is_leap_year(this->year))
{
return 29;
break;
}
else
{
return 28;
break;
}
}
}
bool is_leap_year()
{
if (this->year % 4 != 0) return false;
else
if (this->year % 100 != 0) return true;
else
if (this->year % 400 != 0) return false;
else
return true;
}
date& date::operator=(date rhs)
{
swap(rhs);
return *this;
}
date& date::operator++()
{
this->day_of_week = (this->day_of_week + 1) % 7; //increase weekday
this->day++;
if (++(this->day) > month_limit()) //increase day, if larger than month size...
{
this->day = 1; //reset day to 1
if (++this->month > 12) //increase month, if larger than year size
{
this->month = 1; //reset month to 1
this->year++; //increase year
}
}
return *this;
}
date date::operator++(int)
{
date tmp(*this);
operator++();
return tmp;
}
//adds years on, then months, then days
date& date::operator+=(const date& rhs)
{
this->year += rhs.year;
this->month += rhs.month;
this->day += rhs.day;
if (this->month > 12) //get to the right month
{
this->year = this->month / 12;
this->month = this->month % 12;
}
if (this->day > month_limit())
{
this->month = this->day / month_limit();
this->day = this->day % month_limit();
if (this->month > 12) //recalculate **yes, I know this is currently wrong if more than one month is added on in days**
{
this->year = this->month / 12;
this->month = this->month % 12;
}
}
return *this;
}
inline date date::operator+(date lhs, const date& rhs)
{
lhs += rhs;
return lhs;
}
//subtracts years, then months, then days
date& date::operator-=(const date& rhs)
{
if ((rhs.year < this->year) || ((rhs.year == this->year) && (rhs.month < this->month))
|| (((rhs.year == this->year) && (rhs.month == this->month)) && (rhs.day < this->day)
{
swap(rhs);
}
this->year -= rhs.year;
this->month -= rhs.month;
this->day -= rhs.day;
return *this;
}
inline date date::operator+(date lhs, const date& rhs)
{
lhs += rhs;
return lhs;
}
First of all,
if (i.Month == MonthLimit(i.Month, i.Year))
is comparing the month with the number of days in the month.
Since the first month is 1, and that month has 31 days, you will never increment the month.
Since you never increment the month, you will never increment the year.
(You would probably have spotted this easier if you had named the function "DaysInMonth", or something else that makes it clearer what it returns.)
You want
if (i.Day == MonthLimit(i.Month, i.Year))
Second, MonthLimit is missing a case for October.

How to compare day/month/year in C or C++?

I have a program that asks the user to input to dates then it displays which one is more recent I've done it like this
if (year1>year2 || month1>month2 || day1>day2)
return -1;
if (year1<year2 || month1<month2 || day1<day2)
return +1;
but the output is not quite correct.
Here's a clean way to do it:
#include <tuple> // for std::tie
auto date1 = std::tie(year1, month1, day1);
auto date2 = std::tie(year2, month2, day2);
if (date1 == date2)
return 0;
return (date1 < date2) ? -1 : 1;
The comparisons of std::tie objects are lexicographical, so this returns -1 if date1 is less than date2, 0 if they are the same, and 1 if date1 is greater than date2.
You might be better off defining your own date type (or use boost::datetime).
struct Date
{
unsigned year;
unsigned month;
unsigned day;
};
bool operator<(const Date& lhs, const Date& rhs)
{
return std::tie(lhs.year, lhs.month, lhs.day) <
std::tie(rhs.year, rhs.month, rhs.day);
}
bool operator>(const Date& lhs, const Date& rhs) { .... }
bool operator==(const Date& lhs, const Date& rhs) { .... }
int date_cmp(const Date& lhs, const Date& rhs)
{
// use operators above to return -1, 0, 1 accordingly
}
You need a much more complicated check than that:
if (year1 > year2)
return -1;
else if (year1 < year2)
return +1;
if (month1 > month2)
return -1;
else if (month1 < month2)
return +1;
if (day1 > day2)
return -1;
else if (day1 < day2)
return +1;
return 0;
NOTE: Returning -1 for first is greater than second seems counter-intuititive to me, however I have followed the semantics provided by the OP.
This statement
if (year1>year2 || month1>month2 || day1>day2)
return -1;
tests if any one of the three conditions is true. So, if year1 is higher than year 2, or month1 is higher than month2. Lets stop there. Consider
year1 = 2013, month1 = 12, day1 = 31;
year2 = 2014, month2 = 1, day1 = 1;
We know that, infact, year2 is a higher value, but what happens is
is year1 > year2? no
ok, but is month1 > month2? yes
This makes it look like the first year is a higher value, but it's not, it just a higher month value.
As you get further into C++ you'll find that it's a good idea to try and adopt a convention of making all your comparisons use a single operator (< or >), when you reach a point where you are working with operators you'll understand why.
if (year2 < year1)
return 1;
// we reach this line when year1 <= year2
if (year1 < year2) // elimnate the < case
return -1;
// having eliminated both non-matches,
// we know that by reaching point that both
// dates have the same year. Now repeat for
// the month value.
if (month2 < month1)
return 1;
if (month1 < month2)
return -1;
// year and month must be the same, repeat for day.
if (day2 < day1)
return 1;
if (day1 < day2)
return -1;
return 0; // exact match
//You can try this
int lday,lmonth,lyear;
int nday,nmonth,nyear;
int lhour,lminute;
int nhour,nminute;
sscanf(New_Time,"%d-%d",&nhour,&nminute); //reads the numbers
sscanf(Last_Time,"%d-%d",&lhour,&lminute); //from the string
sscanf(New_Date,"%d-%d-%d",&nday,&nmonth,&nyear);
sscanf(Last_Date,"%d-%d-%d",&lday,&lmonth,&lyear);
//cout << "Last date: " << lday << "-" << lmonth << "-" << lyear <<endl;
//cout << "New date: " << nday << "-" << nmonth << "-" << nyear <<endl;
if(nyear>lyear)
return 0;
if(nyear==lyear) {
if(nmonth > lmonth)
return 0;
if (nmonth == lmonth) {
if(nday > lday)
return 0;
if (nday == lday) {
if( nhour > lhour)
return 0;
if( nhour == lhour) {
if(nminute>lminute) {
//cout << "new time >= last time" << endl <<endl;
return 0;
}
else return 1;
}
else return 1;
}
else return 1;
}
else return 1;
}
else return 1;
struct Day
{
int value;
explicit Day(int value)
{
this->value = value;
}
};
struct Month
{
int value;
explicit Month(int value)
{
this->value = value;
}
};
struct Year
{
int value;
explicit Year(int value)
{
this->value = value;
}
};
class Date {
public:
Date(Day newDay, Month newMonth, Year newYear)
{
_day = newDay.value;
_month = newMonth.value;
_year = newYear.value;
}
int GetYear() const {
return _year;
};
int GetMonth() const {
return _month;
};
int GetDay() const {
return _day;
};
private:
int _year;
int _month;
int _day;
};
bool operator < (const Date& lhs, const Date& rhs)
{
if (lhs.GetYear() == rhs.GetYear()) {
if (lhs.GetMonth() == rhs.GetMonth()) {
if (lhs.GetDay() == rhs.GetDay()) {
return false;
}
return lhs.GetDay() < rhs.GetDay();
}
return lhs.GetMonth() < rhs.GetMonth();
}
return lhs.GetYear() < rhs.GetYear();
};

C++ Function Issue

A while ago I was given the task of converting a Java program to C++.
I've done this, and I've started encountering some odd errors that don't seem to make any sense to me.
The program consists of three files. A main.ccp, a date.ccp and a date.h.
main.ccp
#include <cstdlib>
#include <iostream>
#include "Date.h"
using namespace ::std;
string weekday(Date date);
int main() {
int day, month, year;
cout << "What date (d m y)? ";
cin >> day >> month >> year;
Date event = Date(day, month, year);
cout << ("That was a " + weekday(event));
return 0;
}
string weekday(Date date) {
const string days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
Date trial = Date(1, 1, 1);
int weekday = 6;
if (Date::precedes(trial)) {
return "Mysteryday";
} else {
while (trial.precedes(date)) {
trial.advance();
weekday = (weekday + 1) % 7;
}
return days[weekday];
}
}
Date.ccp
#include "Date.h"
Date::Date(int day, int month, int year) {
day_ = day;
month_ = month;
year_ = year;
}
int Date::getDay () {
return day_;
}
void Date::setDay (int day) {
day_ = day;
}
int Date::getMonth () {
return month_;
}
void Date::setMonth (int month) {
month_ = month;
}
int Date::getYear () {
return year_;
}
void Date::setYear (int year) {
year_ = year;
}
bool Date::isLeapYear () {
bool lear = false;
if (this->year_ <= 1752) {
if (this->year_ % 4 == 0) {
lear = true;
}
}
else {
lear = false;
}
if (this->year_ > 1752) {
if (this->year_ % 4 == 0 && this->year_ % 100 != 0) {
lear = true;
}
else if (this->year_ % 4 == 0 && this->year_ % 100 == 0 && this->year_ % 400 == 0) {
lear = true;
}
else {
lear = false;
}
}
return lear;
}
int Date::daysInMonth () {
// "30 days hath September ... "
switch (this->month_) {
case 9 :
case 4 :
case 6 :
case 11 :
return 30;
default :
return 31;
case 2 :
return this->isLeapYear() ? 29 : 28;
}
}
void Date::advance () {
this->day_;
if (this->day_ == 3 && this->month_ == 9 && this->year_ == 1752) {
day_ = 14;
month_ = 9;
year_ = 1752;
}
if (this->day_ > this->daysInMonth()) {
this->day_ = 1;
this->month_++;
}
if (this->month_ > 12) {
this->month_ = 1;
this->year_++;
}
}
bool Date::precedes (Date date) {
return this->year_ < date->year_
|| this->year_ == date->year_ && this->month_ < date->month_
|| this->year_ == date->year_ && this->month_ == date->month_ && this->day_ < date->day_;
}
Date.h
#ifndef DATE_H
#define DATE_H
class Date {
public:
Date (int day, int month, int year);
int getDay();
void setDay();
int getMonth();
void setMonth();
int getYear();
void setYear();
bool isLeapYear();
int daysInMonth();
void advance();
bool precedes(Date date);
private:
int day_;
int month_;
int year_;
};
#endif /* DATE_H */
I seem to be getting lots of the same errors when I compile.
Date.cpp:97:95: error: base operand of ‘->’ has non-pointer type ‘Date’
I'm not sure if I've done the declaration right or not.
You forgot to put semicolons after your class's closing }.
The class definition for Date is not terminated with a semicolon. Because you #included this file in main.cpp, the first statement after the header is the one that won't parse due to this syntax error; thus you get the error in the wrong place.