I don't know what to do my calender code [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am currently making a calendar algorithm and there is a question about it.
I would like to ask the calendar about changing the first day of the month on the calendar.
This is my calendar code:
#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
int days(int year, int month)
{
int days, i;
for (i = 1; i<month; i++)
{
if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12)
{
days = days + 31;
}
else if (i == 4 || i == 6 || i == 9 || i == 11)
{
days = days + 30;
}
else if (i == 2)
{
days = days + 28;
}
}
days = days + 365 * (year - 1980);
return days;
}
int leapyear(int year, int month)
{
int i;
i = (year - 1977) / 4;
if (year % 4 == 0 && month>2)
{
i++;
}
return i;
}
int weekday(int days)
{
int i;
i = days % 7;
return i;
}
void calendar(int year, int month, int week)
{
int i, j, k, d, cal[42] = { 0 };
char m[12][10] = { "January", "February", "March", "April", "May", "June", "July", "Agust", "September", "Octorber", "November", "December" };
switch (month)
{
case 1: d = 31;
break;
case 2:
{
if ((year % 4) == 0) d = 29;
else d = 28;
}
break;
case 3: d = 31;
break;
case 4: d = 30;
break;
case 5: d = 31;
break;
case 6: d = 30;
break;
case 7: d = 31;
break;
case 8: d = 31;
break;
case 9: d = 30;
break;
case 10: d = 31;
break;
case 11: d = 30;
break;
case 12: d = 31;
break;
}
printf(" < %d %s >\n", year, m[month - 1]);
printf("===========================\n");
printf("Sun Mon Tue Wed Thu Fri Sat");
printf("\n---------------------------\n");
j = 1;
for (i = (week + 2) % 7; i<(d + (week + 2) % 7); i++)
{
cal[i] = j;
j++;
}
k = 0;
for (i = 0; i<6; i++)
{
for (j = 0; j<7; j++)
{
if (cal[k] == 0)
{
printf(" ");
}
else
{
printf("%3d ", cal[k]);
}
k++;
}
if (i<5)
{
printf("\n---------------------------\n");
}
else
{
printf("\n===========================\n");
}
}
}
void main()
{
int year, month, total_days, week;
char YN = 'Y';
do
{
printf("entered year and month with 1980 ~ 2030.(EX) :2003 5)\n");
scanf_s("%d %d", &year, &month);
if (year >= 1980 && year <= 2030 && month >= 1 && month <= 12)
{
printf("Your entered %dYear %dMonth.\n", year, month);
total_days = days(year, month) + leapyear(year, month);
week = weekday(total_days);
calendar(year, month, week);
}
printf("Retry It?(Y/N):");
YN = _getche();
printf("\n");
} while (YN != 'N');
}
I hope these results come out:
< 2003 May >
Sun Mon Tue Wed Thu Fri Sat
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
Retry It?(Y/N):

You never initialize the variable days in the days function.
In C local variables are not automatically initialized to zero. If you don't initialize them, they contain un undetermined value.
So just write:
int days = 0, i;
or better
int days = 0;
for (int i = 1; i<month; i++)
...
I didn't check for other errors or problems, but with the correction the program apparently works fine.

Related

Program gets frozen because of a loop

I'm making a program which calculates the date by giving the program a date and number of days to add to that date in input. In order to do this, I need to make a switch and make it repeat with a loop, but for some reasons, the program gets frozen and doesn't do anything after the user inserts the number of days to add. I've tried removing loop and the program works.
Looking forward to someone who might help me fix this.
Here's the part of the code from getting number of days to add to the end of loop:
cin>>addDays;
while (addDays > 0) {
switch (month) {
//months with 31 days
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
{
finalDay = day + addDays;
if (finalDay > 31) {
addDays = finalDay - 31;
month++;
day = 1;
}
break;
}
//months with 30 days
case 4:
case 6:
case 9:
case 11:
{
finalDay = day + addDays;
if (finalDay > 30) {
addDays = finalDay - 30;
month++;
day = 1;
}
break;
}
//december
case 12:
{
finalDay = day + addDays; //oggi è 10. Voglio aggiungere 30
if (finalDay > 31) { //40 è maggiore di 31
addDays = finalDay - 31; //l'aggiunta 30 diventa 40 - 31 che fa 9
year++;
day = 1;
month = 1;
}
break;
}
//february
case 2:
{
finalDay = day + addDays;
if (year % 4 == 0) {
if (finalDay > 29) {
addDays = finalDay - 29;
month++;
day = 1;
}
}
else {
if (finalDay > 28) {
addDays = finalDay - 28;
month++;
day = 1;
}
}
break;
}
}
}
Your loop runs until addDays falls to <= 0. The problem is, when you add addDays to day, if the resulting finalDay IS within the current month's number of days, you ARE NOT breaking the loop, and you ARE NOT adjusting the values of day or addDays either, so the loop iterates again with the same day and addDays values, calculating the same finalDay value, over and over, endlessly. That is why your program appears frozen.
After fixing that, you are also not taking into account the possibility that addDays might span more than a full month's worth of days. The user could ask to add more than 1 month at a time. So you need to adjust addDays more granularly per month.
Also, when the current month is 2 (February), your leap year calculation is incomplete. Being evenly divisible by 4 is not the only rule you need to check to know if the year is a leap year. A year that is evenly divisible by 4 and 100 but not evenly divisible by 400 is not a leap year.
With that said, try something more like this instead:
bool isLeapYear(int year)
{
return ((year % 4) == 0) &&
(((year % 100) != 0) || ((year % 400) == 0));
}
int lastDayInMonth(int year, int month)
{
switch (month) {
//months with 31 days
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;
//months with 30 days
case 4:
case 6:
case 9:
case 11:
return 30;
//month with 28 or 29 days
case 2:
return isLeapYear(year) ? 29 : 28;
}
return 0;
}
int year, month, day, addDays, lastDay;
...
cin >> addDays;
while (addDays > 0) {
lastDay = lastDayInMonth(year, month);
day += addDays;
if (day <= lastDay) break;
addDays -= (lastDay - day);
if (++month == 13) {
++year;
month = 1;
}
day = 1;
}
That being said, have a look at this answer, which wraps up this kind of logic in a reusable struct named Date that has an overloaded operator+= for adding days.
Thank you very much for your help! You made me understand where the mistake was. I've fixed it and it now works perfectly. But because I'm not as experienced as you and I was having difficulties to read that code, instead of doing as you did, I've added an else to every if inside the switch, which resets addDays to 0, because assignment statements copy their value, they don't move it, for some reasons I wasn't thinking about this stupid and basic thing.
And also thanks for letting me notice about the uncomplete leap year algorithm.
Here's the fixed code. Have a good day!
cin>>addDays;
while (addDays > 0) {
switch (month) {
//months with 31 days
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
{
finalDay = day + addDays;
if (finalDay > 31) {
addDays = finalDay - 31;
month++;
day = 0;
}
else {
addDays = 0;
}
break;
}
//months with 30 days
case 4:
case 6:
case 9:
case 11:
{
finalDay = day + addDays;
if (finalDay > 30) {
addDays = finalDay - 30;
month++;
day = 0;
}
else {
addDays = 0;
}
break;
}
//december
case 12:
{
finalDay = day + addDays; //oggi è 10. Voglio aggiungere 30
if (finalDay > 31) { //40 è maggiore di 31
addDays = finalDay - 31; //l'aggiunta 30 diventa 40 - 31 che fa 9
year++;
day = 0;
month = 1;
}
else {
addDays = 0;
}
break;
}
//february
case 2:
{
finalDay = day + addDays;
if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))) {
if (finalDay > 29) {
addDays = finalDay - 29;
month++;
day = 0;
}
else {
addDays = 0;
}
}
else {
if (finalDay > 28) {
addDays = finalDay - 28;
month++;
day = 0;
}
else {
addDays = 0;
}
}
break;
}
}
}

C++ Program Builds but not printing output

Having trouble determining the cause of this. Everything builds properly just does not print any type of output. I'm sure it is something minuscule so please be understanding and not chew me out for asking such a simple question. Trying my best to learn on my own. The program is supposed to ask you to enter a date dd/mm/yy. Below I have attached the main.cpp and date.h. Thank you for any assistance.
main.cpp
#ifndef DATE_H_
#define DATE_H_
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Date
{
private:
int day, month, year;
char format;
bool isLeapYear() const;
int days_in_month() const;
public:
Date(int month=1, int day=1, int year=2000);
void Input();
void Show();
bool Set(int m, int d, int y);
int GetMonth() const;
int GetDay() const;
int GetYear() const;
bool SetFormat(char f);
void Increment(int numDays=1);
int Compare(const Date& d);
void printJulianDate();
};
#endif
//end of date.h
// date.c
#include "date.h"
// constructor
Date::Date(int month, int day, int year)
{
// set the parameters to default values
this->month = 1;
this->day = 1;
this->year = 2000;
this->format = 'D';
// call the method to set the passed month, day and year
if(!Set(month,day,year))
{
cout<<"Invalid date"<<endl; // display error message if invalid date
}
}
// helper function to return if the year is leap or not
bool Date:: isLeapYear() const
{
return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)));
}
// helper function to return the number of days in the month
int Date::days_in_month() const
{
if(month == 2)
{
if(isLeapYear())
return 29;
else
return 28;
}else if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month ==10 || month==12)
return 31;
else
return 30;
}
// function to input date from the user
void Date:: Input()
{
int m,d,y;
char sep;
// input of date
cout<<"Enter date:";
cin>>m>>sep>>d>>sep>>y;
// loop that continues till the user enters a valid date
while(!Set(m,d,y))
{
cout<<"Invalid date. Try again: ";
cin>>m>>sep>>d>>sep>>y;
}
}
// function to display the date in the format specified
void Date:: Show()
{
if(format == 'D')
{
cout<<month<<"/"<<day<<"/"<<year;
}else if(format == 'T')
{
cout<<setw(2)<<setfill('0')<<month<<"/"<<setw(2)<<setfill('0')<<day<<"/"<<setw(2)<<setfill('0')<<(year%100);
}else if(format == 'L')
{
switch(month)
{
case 1:
cout<<"Jan";
break;
case 2:
cout<<"Feb";
break;
case 3:
cout<<"Mar";
break;
case 4:
cout<<"Apr";
break;
case 5:
cout<<"May";
break;
case 6:
cout<<"June";
break;
case 7:
cout<<"July";
break;
case 8:
cout<<"Aug";
break;
case 9:
cout<<"Sep";
break;
case 10:
cout<<"Oct";
break;
case 11:
cout<<"Nov";
break;
case 12:
cout<<"Dec";
break;
}
cout<<" "<<day<<", "<<year;
}
}
// method to validate the passed arguments and set the date if the arguments represent a valid date
bool Date:: Set(int m, int d, int y)
{
if(y > 1582)
{
if(m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12)
{
if(d < 1 || d > 31)
return false;
else
{
day = d;
month = m;
year = y;
return true;
}
}else if(m == 4 || m == 6 || m == 9 || m == 11)
{
if(d < 1 || d > 30)
return false;
else
{
day = d;
month = m;
year = y;
return true;
}
}else if(m == 2)
{
if((y%400 == 0 ) || ((y%4 == 0) && (y%100) != 0))
{
if(d < 1 || d > 29)
return false;
else
{
day = d;
month = m;
year = y;
return true;
}
}else
{
if(d < 1 || d > 28)
return false;
else{
day = d;
month = m;
year = y;
return true;
}
}
}else
return false;
}else if(y == 1582)
{
if(m >= 10)
{
if(m == 10 || m == 12)
{
if(d < 1 || d > 31)
return false;
else
{
day = d;
month = m;
year = y;
return true;
}
}else if( m == 11)
{
if(d < 1 || d > 30)
return false;
else
{
day = d;
month = m;
year = y;
return true;
}
}else
return false;
}
}
return false;
}
// function to return the month
int Date::GetMonth() const
{
return month;
}
// function to return the day
int Date::GetDay() const
{
return day;
}
// function to return the year
int Date::GetYear() const
{
return year;
}
// function to set the format of the date
bool Date::SetFormat(char f)
{
if(f == 'D' || f == 'T' || f == 'L')
{
format = f;
return true;
}
return false;
}
// function to increment the number of days passed to the date and update the date accordingly
void Date:: Increment(int numDays)
{
day += numDays; // add number of days passed
// loop that continues till the date is valid
while(day > days_in_month())
{
day -= days_in_month();
month++;
if(month > 12) // if month > 12, i.e it represents the first month of next year
{
// increment year and set month to 1
year++;
month = 1;
}
}
}
// function to compare the passed date with this date and return
// -1, if the calling object comes first chronologically
// 0, if the calling object comes first chronologically
// 1, if the objects are the same date
int Date::Compare(const Date& d)
{
if(year < d.year)
return -1;
else if(year > d.year)
return 1;
else
{
if(month < d.month)
return -1;
else if(month > d.month)
return 1;
else
{
if(day < d.day)
return -1;
else if(day > d.day)
return 1;
else
return 0;
}
}
}
// function to print the julian date
void Date:: printJulianDate()
{
int days=0;
// loop to get the day number
for(int i=1;i<month;i++)
{
switch(i)
{
case 1:
days += 31;
break;
case 2:
if(isLeapYear())
days += 29;
else
days += 28;
break;
case 3:
days += 31;
break;
case 4:
days += 30;
break;
case 5:
days += 31;
break;
case 6:
days += 30;
break;
case 7:
days += 31;
break;
case 8:
days += 31;
break;
case 9:
days += 30;
break;
case 10:
days += 31;
break;
case 11:
days += 30;
break;
case 12:
days += 31;
break;
}
}
days += day;
cout<<days<<"-"<<setw(4)<<setfill('0')<<year;
}
Date.h
#ifndef UNTITLED16_DATE_H
#define UNTITLED16_DATE_H
#endif //UNTITLED16_DATE_H
date.cpp
int main(){return 0;}
Since your main function is int main(){return 0;} all your code is doing is: starting up, calling main(), and then returning back to the caller. Of course there is no output involved here...
There are many other details with your code where I am not sure if it will work as you intend. But the minimum change you have to do to see anything is something like this:
#include "Date.h"
#include <iostream>
int main() {
Date theDate;
theDate.Input();
theDate.Show();
// and maybe also
Date theDate2;
theDate2.Input();
if (theDate2.Compare(theDate)) {
std::cout << "true" << std::endl;
}
return 0;
}

Number of Mondays, Tuesdays, etc.. in a given month in C++

I have been able to retrieve the first day of any given month, and I also know how many days are in that month. How do i calculate the amount of mondays, tuesdays, etc.. left in the month? Below is my code is far.
//Set Days in Month
if(Time.Month == 2)
{
if((Time.Year % 400 == 0) || ((Time.Year % 4 == 0) && (Time.Year % 100 != 0)))
Weekend_Status.Month_Days[Time.Month] = 29;
else
Weekend_Status.Month_Days[Time.Month] = 28;
}
else if(Time.Month == 1 || Time.Month == 3 || Time.Month == 5 || Time.Month == 7 || Time.Month == 8 || Time.Month == 10 || Time.Month == 12)
{
Weekend_Status.Month_Days[Time.Month] = 31;
}
else
{
Weekend_Status.Month_Days[Time.Month] = 30;
}
//Set New Month Start Day
if(Time.Day == 1 && Time.Hour == 0 && Time.Minute == 0 && Time.Second == 1)
{
switch(Time.Day_of_Week)
{
case 0: //Sunday
Weekend_Status.Month_Start_Day = 0;
break;
case 1: //Monday
Weekend_Status.Month_Start_Day = 1;
break;
case 2: //Tuesday
Weekend_Status.Month_Start_Day = 2;
break;
case 3: //Wednesday
Weekend_Status.Month_Start_Day = 3;
break;
case 4: //Thursday
Weekend_Status.Month_Start_Day = 4;
break;
case 5: //Friday
Weekend_Status.Month_Start_Day = 5;
break;
case 6: //Saturday
Weekend_Status.Month_Start_Day = 6;
break;
}
}
You could do something like this, where you take advantage of the modulo operator, using it to count all days in the month where the day occurs. Note: Untested.
// example: count how many Wednesdays
int search_day = 3;
int search_day_count = 0;
int start_day = Weekend_Status.Month_Start_Day;
int end_day = Weekend_Status.Month_Days[Time.Month];
// loop through all days for the given month
for (int day = start_day; day <= start_day + end_day; day++)
{
// count all days that are 7 days apart starting from search_day = 3
if (day == search_day || (day - search_day) % 7 == 0)
{
search_day_count++;
}
}

How can I find how many times Friday the 13th appears in a year?

Like the title says, I'm trying to find out how many times Friday the 13th appears in a given year. I have to use a date class and somehow write code to figure it out.
Date.h
#ifndef DATE_H
#define DATE_H
#include <string>
#include <iostream>
using namespace std;
string Month[] = { "", "January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December" };
int daysInMonth[2][13] = { { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
string DOW[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "" };
class Date {
private:
int *month;
int *day;
int *year;
public:
// constructors
Date(int month, int day, int year);
Date(); // default constructor
Date(Date &other); // copy constructor
Date(string mmddyyyy); // constructor that takes a string as parameter e.g "10/31/2012"
~Date();
// overload assignment operator
Date & operator=(Date & rhs);
Date & operator++();
Date & operator++(int);
Date & operator--();
Date & operator--(int);
bool operator ==(Date & rhs);
bool operator != (Date & rhs);
bool operator > (Date & rhs);
bool operator < (Date & rhs);
int operator-(Date & rhs);
Date & operator+(int);
// accessors
int getDay() {
return *this->day;
}
int getMonth() {
return *this->month;
}
int getYear() {
return *this->year;
}
static Date toDate(int doy, int yr) {
int dayOfMonth = doy;
int month = 1;
int isleap = isLeap(yr);
for (int i = 1; i < 13; i++) {
int daysThisMonth = daysInMonth[isleap][i];
if (dayOfMonth <= daysThisMonth) {
break;
}
else {
month++;
dayOfMonth -= daysThisMonth;
}
}
return *new Date(month, dayOfMonth, yr);
}
// display date in the format of mm/day/year e.g. 10/31/2012
void display() {
cout << *this->month << "/" << *this->day << "/" << *this->year;
}
// returns true if the given year is a leap year and false otherwise
static int isLeap(int year) {
return ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0));
}
// returns the day code the the new year day of the given year
static int get_day_code(int year) {
return (year + (year - 1) / 4 - (year - 1) / 100
+ (year - 1) / 400) % 7;
}
// overloading get_day_code that returns the day code of the specific day
static int get_day_code(int year, int month, int day) {
int dayCodeForYear = get_day_code(year);
Date temp(month, day, year);
int doy = temp.dayOfYear() - 1;
int dayCode = (dayCodeForYear + doy) % 7;
return dayCode;
}
int dayOfWeek() { // return the day code of this day
int dayOfYear = this->dayOfYear() - 1;
int firstDayOfTheYear = Date::get_day_code(*this->year);
dayOfYear += firstDayOfTheYear;
return dayOfYear % 7;
}
int dayOfYear() { // returns the day of the year, eg, the day of year for Feb 28 is 59.
int doy = 0;
int isleap = isLeap(*year);
for (int i = 1; i < *month; i++) {
doy += daysInMonth[isleap][i];
}
doy += *day;
return doy;
}
};
Date::Date(int month, int day, int year) {
this->month = new int(month);
this->day = new int(day);
this->year = new int(year);
}
Date::Date() {
this->month = new int(1);
this->day = new int(1);
this->year = new int(2000);
}
Date::Date(Date &other) {
this->month = new int(*(other.month));
this->day = new int(*(other.day));
this->year = new int(*(other.year));
}
Date::Date(string mmddyyyy) {
string mm = mmddyyyy.substr(0, 2);
string dd = mmddyyyy.substr(2, 2);
string yyyy = mmddyyyy.substr(4, 4);
this->month = new int(atoi(mm.c_str()));
this->day = new int(atoi(dd.c_str()));
this->year = new int(atoi(yyyy.c_str()));
}
Date::~Date() {
if (month) delete month;
if (day) delete day;
if (year) delete year;
}
bool Date::operator == (Date & rhs) {
return (*year == *(rhs.year) && *month == *(rhs.month) && *day == *(rhs.day));
}
bool Date::operator != (Date & rhs) {
return !(*this == rhs);
}
bool Date::operator > (Date & rhs) {
if (*year > *(rhs.year)) return true;
else if (*year < *(rhs.year)) return false;
else if (*month > *(rhs.month)) return true;
else if (*month < *(rhs.month)) return false;
else if (*day > *(rhs.day)) return true;
return false;
}
bool Date::operator < (Date & rhs) {
if (*year < *(rhs.year)) return true;
else if (*year > *(rhs.year)) return false;
else if (*month < *(rhs.month)) return true;
else if (*month > *(rhs.month)) return false;
else if (*day < *(rhs.day)) return true;
return false;
}
Date & Date::operator=(Date & rhs) {
*this->month = *rhs.month;
*this->day = *rhs.day;
*this->year = *rhs.year;
return *this;
}
Date & Date::operator++() {
Date tmp = *this + 1;
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *this;
}
Date & Date::operator++(int) {
Date tmp = *this + 1;
Date * output = new Date(tmp);
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *output;
}
Date & Date::operator--() {
Date tmp = *this + -1;
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *this;
}
Date & Date::operator--(int) {
Date tmp = *this + -1;
Date * output = new Date(tmp);
*this->month = *tmp.month;
*this->day = *tmp.day;
*this->year = *tmp.year;
return *output;
}
int Date::operator-(Date & rhs) {
int yearsDiff = *this->year - *rhs.year;
int daysDiff = this->dayOfYear() - rhs.dayOfYear();
daysDiff += yearsDiff * 365;
return daysDiff;
}
Date & Date::operator+(int) {
int n = 0;
int doy = dayOfYear();
int newDoy = doy + n;
int yearsDiff = newDoy / 365;
newDoy = newDoy % 365;
int newYear = *this->year + yearsDiff;
Date newDate = Date::toDate(newDoy, newYear);
return *new Date(newDate);
}
#endif
This is the code I've been messing with for a while:
Source.cpp
#include <iostream>
#include <iomanip>
#include "Date.h"
using namespace std;
void iterateMonth(int);
bool isFriday13th();
string dayofweek[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "" };
string month[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" };
//int dayInMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
//int dayInMonthLeap[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
void iterateMonth(int year) {
int dayCode, month, daysInMonth, day, u;
bool leapYear;
cout << year;
// returns the day on which January 1 of year begins.
dayCode = Date::getDayCode(year);
// returns true if year is a leap year, false otherwise
leapYear = Date::isLeap(year);
// month is 0 for Jan, 1 for Feb, etc.
for (month = 1; month <= 12; month++)
{
switch (month)
{
case 1:
cout << "\n\nJanuary\n";
daysInMonth = 31;
break;
case 2:
cout << "\n\nFebruary\n";
if (leapYear)
daysInMonth = 29;
else
daysInMonth = 28;
break;
case 3:
cout << "\n\nMarch\n";
daysInMonth = 31;
break;
case 4:
cout << "\n\nApril\n";
daysInMonth = 30;
break;
case 5:
cout << "\n\nMay\n";
daysInMonth = 31;
break;
case 6:
cout << "\n\nJune\n";
daysInMonth = 30;
break;
case 7:
cout << "\n\nJuly\n";
daysInMonth = 31;
break;
case 8:
cout << "\n\nAugust\n";
daysInMonth = 31;
break;
case 9:
cout << "\n\nSeptember\n";
daysInMonth = 30;
break;
case 10:
cout << "\n\nOctober\n";
daysInMonth = 31;
break;
case 11:
cout << "\n\nNovember\n";
daysInMonth = 30;
break;
case 12:
cout << "\n\nDecember\n";
daysInMonth = 31;
break;
}
//cout << "\n\nSun Mon Tue Wed Thu Fri Sat\n";
for (int i = 0; i < (sizeof(dayofweek) / sizeof(dayofweek[0])); i++)
{
cout << dayofweek[i] << " ";
}
cout << endl;
for (day = 1; day <= dayCode * 5; day++)
{
cout << " ";
}
for (day = 1; day <= daysInMonth; day++)
{
cout << setw(3) << day;
if ((day + dayCode) % 7 > 0)
{
cout << " ";
}
else
cout << endl;
}
dayCode = (dayCode + daysInMonth) % 7;
}
}
//bool isFriday13th() {
//
//}
int main() {
int year;
//cout << "Please enter a year: ";
cout << "Final ";
cin >> year;
iterateMonth(year);
}
One idea I got from someone was to create a Date object for January 13th, use the dayOfWeek method to check if it's Friday, and if not, increment until I reach Friday, then jump ahead 7 and use getDay to check if it's 13. I tried this out with this:
Date tmp(1, 13, year);
int dc = tmp.dayOfWeek(); // return day code
tmp.display();
cout << endl;
++tmp;
tmp.display();
cout << endl;
I expected the tmp.display(); line to show 1/13/2013 (giving 2013 as the year), which it did, but the ++tmp line gave the same result. I also thought that I would have to somehow find the day code that corresponds to Friday (right now dc is 0), but I couldn't figure that out.
Also, another post related to the same problem said that every month that begins in Sunday will have Friday the 13th, so I tried thinking of how to implement that. Maybe somewhere in the first for loop (above the switch statement) I could check something like if (firstDay = Sunday) { cout << "Friday13th exists in " << month << endl; }
That's kinda horrible pseudo-code, but it was the idea I had going. Anyone have ideas? Any help would be appreciated, and thank you in advance.
You can do this without having to do a bunch of calls to a function that gets the day of the year. If you know the date of the first Sunday in January, then there's nothing to it. Just some basic math.
For 2013, the first Sunday in January was the 6th. So the 13th was a Sunday. We know that if the first Sunday in January is the 6th, then the first Sunday in February is the 3rd. Add 10 days for the 13th. That's a Wednesday.
How do I know that the first Sunday in February is the 3rd? Because the that's how the calendar works. If you take the date of the first Sunday in January, add 4 and mod 7, that'll give you the date of the first Sunday in February. The calendar is fixed that way; given the first Sunday in January, you can easily compute the first Sunday of any month using modulo 7 arithmetic.
The offsets are:
Normal Year: 0 4 4 1 6 3 1 5 2 0 4 2
Leap Year: 0 4 3 0 5 2 0 4 1 6 3 1
If you want to know what months have Friday fall on the 13th, then the next Sunday is the 15th, meaning that the first Sunday of the month has to be the 1st.
Given the table above, if the first Sunday in January is the 1st, then in a normal year you'll have two months with Friday the 13th: January and October. If it's a leap year, then you'll have January, April, and July. This year the first Sunday was the 6th, so you need months with an offset of 2. So September and December.
If the month offset plus the date of the first Sunday in January is equal to 8, then the month has a Friday the 13th.
I played with this as a memory trick some time ago. See Now what day is that? for a longer explanation.
Well... For starters - it would be much easier for you to make your Date class if you would use the <ctime> header and the functions included there.
Secondly - you got an overloaded function: int get_day_code(int year, int month, int day). If it does what it should (or more like: what the description says), in order to check how many times Friday the 13th is in a year, you would probably do:
int howManyFridays = 0;
for(int i=0;i<12;i++)
if(get_day_code(year,i,13)==CODE_FOR_FRIDAY) howManyFridays++;
return howManyFridays;

C++ Incomplete Code about dates, what is the better solution?

Im writing a code that, if you input your birthday date and any other date, it returns the total number of years, months and day that you are alive.
Obs.:including (leap) bissextile years.
Obs.2:for invalid dates, the output must be "data invalida" (invalid date in portuguese).
Inputs/Outputs:
Obs.: The date format is in the brazillian standard, the format is Day / Month / Year.
8 //the first input is the number of inputs that you will test.
Input 1: 29/02/2000
Input 2: 01/03/2001
Output: 1 0 1
Input 1: 29/02/2000
Input 2: 28/02/2001
Output: 1 0 0
Input 1: 29/12/2012
Input 2: 13/01/2013
Output: 0 0 15
Input 1: 27/05/2012
Input 2: 27/05/2013
Output: 1 0 0
Input 1: 01/01/2012
Input 2: 05/01/2013
Output: 1 0 4
Input 1: 13/05/1966
Input 2: 05/02/2015
Output: 48 8 23
Input 1: 29/02/2003
Input 2: 4/05/2012
Output: data invalida
Input 1: 14/13/1995
Input 2: 7/8/1996
Output: data invalida
The Code:
#include <iostream>
#include <cstdio>
using namespace std;
int verificar(int ano)
{
if (((ano % 4 == 0) && (ano % 100 != 0)) || (ano % 400 == 0))
return 1;
else
return 0;
}
int checkdia(int dia, int mes, int ano){
if (dia>0)
if (((mes==1)||(mes==3)||(mes==5)||(mes==7)||(mes==8)||(mes==10)||(mes==12)) && (dia<=31))
return 1;
else{
if (((mes==4)||(mes==6)||(mes==9)||(mes==11)) && (dia<=30))
return 1;
else{
if ((mes==2) && (dia<=28))
return 1;
else{
if ((((verificar(ano))==true)&&(dia<=29))&&(mes==2))
return 1;
else
return 0;
}
}
}
else
return 0;
}
int checkmes(int mes)
{
if ((mes>0) && (mes<=12))
return 1;
else
return 0;
}
int checkano(int ano)
{
if ((ano>0) && (ano<11000))
return 1;
else
return 0;
}
int main(){
int numerodetestes, mes1, mes2, dia1, dia2, ano1, ano2, teste11, teste12, teste13, teste21, teste22, teste23;
cin>>numerodetestes;
for(int c=0;c<=numerodetestes;c++){
scanf("%d/%d/%d", &dia1, &mes1, &ano1);
scanf("%d/%d/%d", &dia2, &mes2, &ano2);
teste11=checkano(ano1);
teste12=checkdia(dia1,mes1,ano1);
teste13=checkmes(mes1);
teste21=checkano(ano2);
teste22=checkdia(dia2,mes2,ano2);
teste23=checkmes(mes2);
if ((dia1==29)&&(mes1==02))
dia1=28;
if ((teste11+teste12+teste13+teste21+teste22+teste23)==6){
total=((365*(ano2-ano1))+sexto);
//... incomplete part ...//
}
else
cout<<"data invalida"<<endl;
}
return 0;
}
Glossary:
dia: day
mes: month
ano: year
numerodetestes: number of tests
verificar: function for bissextile
check(...): function to check "X"
teste"XX": int variable that will receive a 0 or 1 of a check function.
THE PROBLEM IS: I cant figure out how to calculate it in an organized way.
You should use bool instead of int for your return values :
bool verificar(int ano)
{
return ((ano % 4 == 0) && (ano % 100 != 0)) || (ano % 400 == 0));
}
Also your check functions could be greatly simplified :
bool checkmes(int mes) {
return ( (mes > 0) && (mes <= 12) );
}
bool checkano(int ano) {
return ( (ano > 0) && (ano < 11000) );
}
bool checkdia(int dia, int mes, int ano) {
if(dia < 1 || dia > 31) return false;
if(mes%2 == 0 && dia >30) return false;
if(mes == 2 && dia >28) return verificar(ano);
return true;
}
Then you could write something like :
bool checkdata(int dia, int mes, int ano) {
return ( checkano(ano) && checkmes(mes) && checkdia(dia, mes, ano) );
}
Which would allow you to write :
if( !checkdata(dia1,mes1,ano1) || !checkdata(dia2,mes2,ano2) ) {
cout<< "data invalida" <<endl;
}
Now for the main problem, you could easily get an estimation of the number of day between two dates, but you can't easily get the real number, because dates are nothing but logical. You would have to take into account all calendar modifications across history.
For an easy estimation, I would first add/subtract the dates offset to the first of January, and then add the year difference :
bool isLeap(int year) {
     return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
int monthLengths[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int monthLength(int month, int year) {
int n = monthLengths[month-1];
if(month == 2 && isLeap(year)) n += 1;
return n;
}
int yearLength(int year) {
return isLeap(year) ? 366 : 365;
}
int nDay = 0; /* day counter */
/* subtract data1 offset to 01/01 */
nDay -= dia1;
for(int i = mes1; i > 1; --i) {
nDay -= monthLength(i - 1, ano1);
}
/* add data2 offset to 01/01 */
nDay += dia2;
for(int i = mes2; i > 1; --i) {
nDay += monthLength(i - 1, ano2);
}
/* add year offset */
for(int i = ano2; i > ano1; --i) {
nDay += yearLength(i);
}
cout << "Difference = " << nDay << " days" << endl;