Вы слишком усложняете процедуру приращения.
Я на самом деле все еще пытаюсь выяснить, как все это подходит (кромки и т. Д.), Но кажется, что вы пытались делать каждый день/месяц/год независимо.
Вы можете сделать все ваши в приращение простой функции, как это:
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
}
}
}
Логика проще, потому что я подошел к ней в несколько иначе, чем вы, кажется, сделали.
В приведенной выше функции я увеличиваю наименьшую единицу сначала (день), проверяю переполнение, а затем при необходимости перемещаюсь до месяца (и так далее).
Это работает так же, как цифры циферблата пробега автомобиля только тикают, когда циферблат достигает 10
и возвращается к 0. Или, добавив от 1 до 9 и «переполненный» цифрой 10 цифр.
В противном случае ваш код хорош. Оператор Switch для MonthLimit
был хорошим выбором. я бы добавить переключатель заявление в функции возвращает строку в день недели:
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";
}
и print_date
функции тоже:
void print_date(Date d)
{
std::cout<< printable_DOW(d.DayOfWeek)
<< ", " << d.Day << "." << d.Month << "." d.Year;
}
, и это довольно легко поставить все это вместе и использовать также:
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);
}
Как класс: Это в основном здесь, и (в основном) работы. Не стесняйтесь редактировать людей!
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;
}
Как и в сторону, почему 'выхода (0);' вместо (неявное) 'вернуть 0;' в конце 'main'? – Deduplicator
Это то, что меня просят сделать. Это как-то связано с тем, что мой код отправляется на Linux-машину, у которой, вероятно, возникают проблемы с простым «возвратом 0;». – Chiffa
Нет, Linux, безусловно, прекрасен с более идиоматическим кодом. Взгляните на второй оператор 'if' в цикле. Это ... так неправильно (логика). Кроме того, подумайте о том, чтобы ввести код нормализации даты в функцию-член 'normalize()'. – Deduplicator