I had to write a program for my laboratory at college. In the program I want to compare two dates in the format day/month/year. I know how to do that,but without including the hour.For now I'm converting the date into days passed since year 0000 and simply compare these two values. The problem is my teacher told me to add hours and now I dont know how to compare this. Any suggestions? Present code bellow
.h File
class timee
{
int day;
int month;
int year;
int hour;
long int count;
public:
timee();
timee(int,int,int,int);
long int daysCount();
bool operator>(const timee &);
bool operator>=(const timee &);
bool operator<=(const timee &);
bool operator==(const timee &);
timee & operator=(const timee &);
timee & operator+=(int);
timee & operator-=(int);
long int operator-(timee &);
friend ostream & operator<<(ostream &, const timee &);
friend istream & operator>>(istream &, timee &);
};
Here the .cpp file
timee::timee():day(0),month(0),year(0),hour(0),count(0){}
timee::timee(int day,int month,int year,int hour):day(day),month(month),year(year),hour(hour)
{
count = daysCount();
}
/*calculating the number of days that have passed since year 0000*/
long int timee::daysCount()
{
int month_days[] = {0,31,59,90,120,151,181,212,243,273,304,334};
// calculate number of leap years.
int leapyears = year / 4;
if (isLeapYear(year) && month < 3)
{
// If this is a leap year
// And we have not passed Feburary then it does
// not count.....
leapyears --;
}
// convert year/month/day into a day count
count = year * 365 + month_days[month-1] + day + leapyears;
return count;
}
/*convering the date from days since year 0000 to year/month/day format */
timee timee::dateConversion()
{
int month_days[] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
//calculate number of leap year
int leapyears = year / 4;
if (isLeapYear(year) && month < 3)
{
// If this is a leap year
// And we have not passed Feburary then it does
// not count.....
leapyears --;
}
//calculating year
year = (count-leapyears)/365;
for(unsigned int i = 0; i <= 12; i++)
{
if((count-leapyears)%365 > month_days[i])
{
month = i+1;
}
}
day = ((count-leapyears)%365)-month_days[month-1];
return *this;
}
bool timee::operator>(const timee &obj)
{
return count>obj.count;
}
bool timee::operator>=(const timee &obj)
{
//if((count>=obj.count) && (hour>=obj.hour)) return true;
//else if((count<=obj.count) && (hour>obj.hour))return false;
}
bool timee::operator<=(const timee &obj)
{
return count<=obj.count;
}
bool timee::operator==(const timee &obj)
{
return count==obj.count;
}
timee & timee::operator=(const timee &obj)
{
day=obj.day;
month=obj.month;
year=obj.year;
hour=obj.hour;
count=obj.count;
return *this;
}
timee & timee::operator+=(int value)
{
count+=value;
this->dateConversion();
return *this;
}
timee & timee::operator-=(int value)
{
count-=value;
this->dateConversion();
return *this;
}
long int timee::operator-(timee &obj)
{
return count - obj.count;
}
ostream & operator<<(ostream &os, const timee &obj)
{
os << "Date: " << obj.day << "." << obj.month << "." << obj.year << " Hour: " << obj.hour << " " << obj.count << endl;
return os;
}
istream & operator>>(istream &is, timee &obj)
{
cout << "Type day, month and year" << endl;
is >> obj.day >> obj.month >> obj.year >> obj.hour;
obj.daysCount();
return is;
}
There is one of my attempts to overload the >= operator. Please help.
count in your algorithm refers to the number of days passed since year 0.
Though, the smallest precision you should have now is not a day, but an hour. So you should simply create a variable totalHours being the number of hours passed since year 0.
//Calculate number of days since year 0
count = year * 365 + month_days[month-1] + day + leapyears;
//Convert to number of HOURS since year 0, and add additional hour
totalHours = count*24 + hour;
There are 3 possible relations between count and obj.count inside operator >=. Either count < obj.count or count == obj.count or count > obj.count. The same holds for hours and obj.hours. That gives 3 * 3 = 9 possible combinations. Write down what the result of the operator should be for each combination and then find the easiest way to express that in your code.
Note that you don't need to do this for each comparison operator. Typically you implement operator < and then define the others in terms of that one.
Related
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;
}
I'm working on a debugging console app for school, and I get an error when compiling the program.
//DEBUG9-4
//This program creates Student objects
//and overloads < to compare student year in school
#include<iostream>
#include<string>
using namespace std;
class Student
{
private: //MISSING :
int stuID;
int year;
double gpa;
public:
Student(const int i, const int y, const double g); // NO VARIABLES DECLARED HERE
void showYear(); //MISSING THE CURLY BRACES
bool operator < (const Student);
};
Student::Student(const int i, const int y, const double g) // VARIABLES WERE NOT MATCHING
{
stuID = i;
year = i;
gpa = g; // VARIABLE g WAS POST TO BE THE "gpa" VARIABLE
}
void Student::showYear()
{
cout << year;
}
int Student::operator < (const Student otherStu)
{
bool less = false;
if (year < otherStu.year)
less = true;
return less;
}
int main()
{
Student a(111, 2, 3.50), b(222, 1, 3.00);
if(a < b)
{
a.showYear();
cout << " is less than ";
b.showYear();
}
else
{
a.showYear();
cout << " is not less than ";
b.showYear();
}
cout << endl;
return 0;
}
Line: 28 Error: prototype for 'int Student::operator < (const Student& otherStu)' dose not match any in class Students.
Line: 16 Error: candidate is: bool Student::operator<(Student).
You wanted to implement it like this:
bool Student::operator < (const Student otherStu)
{
bool less = false;
if (year < otherStu.year)
less = true;
return less;
}
Because now your definition and declaration doesnt match, thay have different return value.
or you can doi just:
bool Student::operator < (const Student b)
{
return year < b.year ? true : false;
}
Hy! This is my first question on this site. Sorry for my English, if I will make mistakes:(
So, my problem is the following. I have simple class Date.
class Date
{
public:
Date();
Date(unsigned short day, unsigned short month, unsigned short year);
Date(const Date &date);
unsigned short getDay();
unsigned short getMonth();
unsigned short getYear();
void setDay(unsigned short day);
void setMonth(unsigned short month);
void setYear(unsigned short year);
void printOnScreen()const;
friend
std::ostream& operator<< (std::ostream& out, const Date& date) {
out << date.day << "." << date.month << "." << date.year;
return out;
}
friend
bool operator<(const Date& a, const Date& b) {
if (a == b) {
return false;
}
if (a.year < b.year) {
return true;
}
if (a.month < b.month) {
return true;
}
if (a.day < b.day) {
return true;
}
return false;
}
friend
Date& operator-(Date& a) {
return a;
}
friend
Date operator-(const Date& a, const Date& b) {
return Date(
abs(a.day - b.day),
abs(a.month - b.month),
abs(a.year - b.year)
);
}
friend
bool operator==(const Date& date1, const Date& date2) {
return (
date1.day == date2.day &&
date1.month == date2.month &&
date1.year == date2.year
);
}
virtual ~Date();
private:
friend KeyHasher;
unsigned short day;
unsigned short month;
unsigned short year;
};
In my main function I call sort like in this example, and after it get the error.
auto dates = {
Date(1, 5, 2016),
Date(3, 2, 2015),
Date(3, 3, 2000),
Date(2, 1, 1991),
Date(1, 8, 2200),
Date(1, 8, 2200),
Date(1, 8, 2020),
Date(21, 9, 2016)
};
vector<Date> v1(dates);
sort(
v1.begin(),
v1.end(),
less<Date>()
);
What is wrong, I don't understand. Thank you for help.
Your operator < is indeed incorrect, use std::tie:
auto as_tuple(const Date& d) {
return std::tie(d.year, d.month, d.day);
}
bool operator<(const Date& lhs, const Date& rhs) {
return as_tuple(lhs) < as_tuple(rhs);
}
bool operator == (const Date& lhs, const Date& rhs) {
return as_tuple(lhs) == as_tuple(rhs);
}
Try to change your conditions like:
if (a.year < b.year)
return true;
else if (a.year > b.year)
return false;
else // a.year == b.year
{
if (a.month < b.month)
return true;
else if (a.month > b.month)
return false;
else // a.month == b.month
{
if (a.day < b.day)
return true;
else
return false;
}
}
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();
};
Error:
..\Record.cpp: In function `std::ostream& operator<<(std::ostream&, Record&)':
..\Record.cpp:83: error: no match for 'operator<<' in 'out << Record::date()()'
Record.cpp:
/*
* Record.cpp
*
* Created on: Jun 13, 2010
* Author: DJ
*/
#include <iostream>
#include "Record.h"
using std::string;
using std::istream;
using std::ostream;
Record::Record() {
}
Record::Record(Date inDate) {
_date = inDate;
}
Record::Record(Date inDate, Time inTime) {
_date = inDate;
_time = inTime;
}
Record::Record(Date inDate, Time inTime, string inDescription) {
_date = inDate;
_time = inTime;
_description = inDescription;
}
Record::~Record() {
}
Time Record::time() {
return _time;
}
void Record::time(Time inTime) {
_time = inTime;
}
Date Record::date() {
return _date;
}
void Record::date(Date inDate) {
_date = inDate;
}
string Record::description() {
return _description;
}
void Record::description(string inDescription) {
_description = inDescription;
}
void Record::operator=(Record record) {
_date = record.date();
_time = record.time();
_description = record.description();
}
istream &operator>>(istream &in, Record &record) {
Time inTime;
Date inDate;
string inDescription;
in >> inDate >> inTime >> inDescription;
record.date(inDate);
record.time(inTime);
record.description(inDescription);
return in;
}
ostream &operator<<(ostream &out, Record &record) {
out << record.date() << " " << record.time() << " " << record.description();
return out;
}
Date.cpp:
/*
* Date.cpp
*
* Created on: Jun 13, 2010
* Author: DJ
*/
#include "Date.h"
#include <iostream>
using std::istream;
using std::ostream;
Date::Date() {
_day = 1;
_month = 1;
_year = 1999;
}
Date::Date(unsigned int inDay) {
day(inDay);
_month = 1;
_year = 1999;
}
Date::Date(unsigned int inDay, unsigned int inMonth) {
day(inDay);
month(inMonth);
_year = 1999;
}
Date::Date(unsigned int inDay, unsigned int inMonth, unsigned int inYear) {
day(inDay);
month(inMonth);
year(inYear);
}
Date::~Date() {
}
void Date::day(unsigned int inDay) {
assert(inDay <= daysInMonth());
_day = inDay;
}
unsigned int Date::day() {
return _day;
}
void Date::month(unsigned int inMonth) {
assert(inMonth <= 12);
_month = inMonth;
}
unsigned int Date::month() {
return _month;
}
void Date::year(unsigned int inYear) {
_year = inYear;
}
unsigned int Date::year() {
return _year;
}
void Date::operator=(Date date) {
day(date.day());
month(date.month());
year(date.year());
}
istream &operator>>(istream &in, Date &date) {
char dummy;
unsigned int day, month, year;
in >> month >> dummy >> day >> dummy >> year;
date.day(day);
date.month(month);
date.year(year);
return in;
}
ostream &operator<<(ostream &out, Date &date) {
out << date.month() << "/" << date.day() << "/" << date.year();
return out;
}
unsigned int Date::daysInMonth() {
if(_month == 1 || _month == 3 || _month == 5 || _month == 7 || _month == 8 || _month == 10 || _month == 12)
return 31;
else
return 30;
}
Time is basically the same as date.
Your operator<< should take const references (const Date &).
If your operators take non-const references, they won't work with temporary objects (such as the one returned from Record::date). This is what's causing the error.
Note that changing to const references means you will need to change any member functions called (e.g. Date::month) to be const. This is good practice anyway.
Another option is to pass the parameter by value, which will invoke the copy constructor. const references are usually preferred because they are generally faster, and you shouldn't need to invoke non-const members anyway.
Because the reading operator needs "read-only" access to the variable :
ostream &operator<<(ostream &out, const Record &record) //<< const
ostream &operator<<(ostream &out, const Date &date) //<< const
Here are some explanations about member function constness, as you'll have to make sure some accessors are const : http://www.parashift.com/c++-faq-lite/const-correctness.html