1
\$\begingroup\$

You will prompt a user for a month, a day and a year. You will then tell the user how many days since January 1 of that year the input date is. For example if the user inputs a 3 for the month, a 2 for the date, and 2000 for the year the program outputs the number of days as being 62. Note 2000 is a leap year. Therefore you must test to see if a year is a leap year when doing this problem.

I'm trying to build onto this one:

#include<iostream>

using namespace std;

int main()
{
int days_in_months[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

int day;

int month;

int year;

int days_difference;

int reg_year = 365;

int leap_year = 366;



cout << "Program to calculate how many days are in between the date and the start of the year." << endl;
cout << endl;

cout << "Please enter the date by day, month, year." << endl;
cout << endl;

cout << "First date:: " << endl;
cout << endl;

cout << "Day: ";
cin >> day;
if (day > 31 || day <= 0)
{
    cout << "Incorrect day entered" << endl;
    cin.ignore();
    return 0;
}
cout << "Month: ";
cin >> month;
if (month > 12 || month <= 0)
{
    cout << "Incorrect Month entered" << endl;
    cin.ignore();
    return 0;
}
cout << "Year: ";
cin >> year;

if (year > 9999 || year < 0)
{
    cout << "Incorrect year entered" << endl;
    cin.ignore();
    return 0;

or just edit this one:

#include<iostream>

using namespace std;

int main()
{
int days_in_months[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

int first_day, second_day;

int first_month, second_month;

int first_year, second_year;

int years_difference, days_difference;

int months_total;

int reg_year = 365;


cout << "Program to calculate how many days are in between the day/month/year entered." << endl;
cout << endl;

cout << "Please enter the date by day, month, year." << endl;
cout << endl;

cout << "First date:: " << endl;
cout << endl;

cout << "Day: ";
cin >> first_day;
if (first_day > 31 || first_day <= 0)
{
    cout << "Incorrect day entered" << endl;
    cin.ignore();
    return 0;
}
cout << "Month: ";
cin >> first_month;
if (first_month > 12 || first_month <= 0)
{
    cout << "Incorrect Month entered" << endl;
    cin.ignore();
    return 0;
}
cout << "Year: ";
cin >> first_year;

if (first_year > 9999 || first_year < 0)
{
    cout << "Incorrect Year Entered" << endl;
    cin.ignore();
    return 0;
}

cout << endl;
cout << "\nSecond date:: " << endl;
cout << endl;

cout << "Day: ";
cin >> second_day;
if (second_day > 31 || second_day <= 0)
{
    cout << "Incorrect day entered" << endl;
    cin.ignore();
    return 0;
}
cout << "Month: ";
cin >> second_month;
if (second_month > 12 || second_month <= 0)
{
    cout << "Incorrect Month entered" << endl;
    cin.ignore();
    return 0;
}
cout << "Year: ";
cin >> second_year;
if (second_year > 9999 || second_year < 0)
{
    cout << "Incorrect Year Entered" << endl;
    cin.ignore();
    return 0;
}


/////////////////////////////Years/////////////////////////////////


if (first_year == second_year)
{
    years_difference = 0;
}
else

{
    if (first_year % 4 == 0 && first_year % 100 != 0 || first_year % 400 == 0)
    {
        if (second_year % 4 == 0 && second_year % 100 != 0 || second_year % 400 == 0)
        {
            if (first_year > second_year)
            {
                years_difference = (first_year - second_year) * (reg_year)+2;
            }
            else
            {
                years_difference = (second_year - first_year) * (reg_year)+2;
            }
            if (second_month > first_month)
            {
                if (days_in_months[first_month - 1] > days_in_months[1])
                {
                    --years_difference;
                }
            }
        }
        else
        {
            if (first_year > second_year)
            {
                years_difference = (first_year - second_year) * (reg_year)+1;
            }
            else
            {
                years_difference = (second_year - first_year) * (reg_year)+1;

            }
            if (first_month > second_month)
            {
                if (days_in_months[second_month - 1] > days_in_months[1])
                {
                    --years_difference;
                }
            }
        }
    }
    else

    {
        if (first_year > second_year)
        {
            years_difference = (first_year - second_year) * (reg_year);
        }
        else
        {
            years_difference = (second_year - first_year) * (reg_year);
        }
    }
}

/////////////////////////////Months////////////////////////////////////


if (first_month == second_month)
{
    months_total = 0;
}
else
{
    if (first_month > second_month)
    {
        for (int i = (first_month - 1); i > (second_month - 1); i--)
        {
            static int months_total_temp = 0;
            months_total_temp += days_in_months[i];
            months_total = months_total_temp;
        }
    }
    else
    {
        for (int i = (first_month - 1); i < (second_month - 1); i++)
        {
            static int months_total_temp = 0;
            months_total_temp += days_in_months[i];
            months_total = months_total_temp;
        }
    }
}

////////////////////////////Days//////////////////////////////////

int days_total;

if (first_day == second_day)
{
    days_difference = 0;
    days_total = (years_difference + months_total) - days_difference;
}
else
{
    if (first_day > second_day)
    {
        days_difference = first_day - second_day;
        days_total = (years_difference + months_total) - days_difference;
    }
    else
    {
        days_difference = second_day - first_day;
        days_total = (years_difference + months_total) + days_difference;
    }
}

//////////////////////////In Between Leap Years///////////////////////////////

if (first_year == second_year)
{
}
else
{
    if (first_year > second_year)
    {
        for (int i = (second_year + 1); i < first_year; i++)
        {
            if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)
            {
                cout << endl;

                cout << i << endl;
                ++days_total;
            }
        }
    }
    else
    {
        for (int i = (first_year + 1); i < second_year; i++)
        {
            if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)
            {
                cout << endl;
                cout << i << endl;
                ++days_total;
            }
        }
    }
}

//////////////////////////Output//////////////////////////////////


cout << endl;
cout << "\nThe total days in between your dates are: " << days_total << endl;
cout << endl;

cin.get();
cin.ignore();
return 0;
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Looks better! I'm not sure if you're still encountering issues or asking for more code (both are off-topic), but I could still provide a few pointers. \$\endgroup\$ – Jamal Nov 14 '13 at 4:20
  • \$\begingroup\$ Are you allowed to factor code into functions, like taking that leap year logic into some bool isLeapYear(int year) function? \$\endgroup\$ – Mathieu Guindon Nov 14 '13 at 4:23
  • \$\begingroup\$ There are also missing closing curly braces in the first block, but I'm too tired to fix all the indentation. In general, all that can be fixed by using spaces instead of tabs. \$\endgroup\$ – Jamal Nov 14 '13 at 4:27
  • \$\begingroup\$ everything is strictly if statements, and its killing me. i have to take the current program and completely redo it with a set date and with only if statements. \$\endgroup\$ – Keith Nov 14 '13 at 4:27
  • 1
    \$\begingroup\$ @retailcoder: I don't think that's quite the goal. The OP did mention a certain form (if-statements), but not code-golfing or obfuscation specifically. \$\endgroup\$ – Jamal Nov 16 '13 at 18:57
6
\$\begingroup\$

There is a much easier technique to use.

Assign numbers for each day (0->N). Given a data calculate the number for that day. The difference is simply subtracting the two numbers.

day1 = GetIdOf(year1, month1, day1);
day2 = GetIdOf(year2, month2, day2);

std::cout "Diff: " << abs(day1 - day2) << "\n";

GetIdOf

int GetIdOf(int year, int month, int day)
{
    // Note: No month 0.
    //       We are counting the all the days up to this month.
    //       In Jan (month 1) there are no days before.
    //       In Feb (month 2) we count all the days in Jan
    //       In Mar (month 3) we count all the days in Jan + Feb
    //       etc ...  (leap years sorted separately).
    static int daysInMonth[] = {0,0,31,59,....};

    int result = year * 365;
    result     += leapYearsSince0(year-1);   // don't include this year.
    result     += daysInMonth[month];
    result     += isLeapYear(year) & month > 2 ? 1 : 0;
    result     += day;
    return result;
}

Years:

if (year > 9999 || year < 0)

There is no year 0 in the Gregorian calender. It goes from -1 (or 1 BC) to 1 (or 1 AD). Also I would not go back that far. Limit your application to years above 1900. Before that it gets very complicated and actually depends on what country you are in.

Or (assuming this is just a school project) you can make the assumption we used the Gregorian all the way back to pre-history.

Remove Repeated code.

Replaece repeated code with a function call.

if (day > 31 || day <= 0)
{
    cout << "Incorrect day entered" << endl;
    cin.ignore();
    return 0;
}
cout << "Month: ";
cin >> month;
if (month > 12 || month <= 0)
{
    cout << "Incorrect Month entered" << endl;
    cin.ignore();
    return 0;
}
cout << "Year: ";
cin >> year;

if (year > 9999 || year < 0)
{
    cout << "Incorrect year entered" << endl;
    cin.ignore();
    return 0;
}

That would be so much simpler to write as:

int getAndCheckRange(int max, int min, std::string const& type)
{
    int val;
    cout << type << ": ";
    cin >> val;

    if (val > max || val < min)
    {
        cout << "Incorrect " << type << " entered" << endl;
        cin.ignore();
        throw std::runtime_error("Failed");
    }
}

.....

getAndCheckRange(day,   31,   0, "day");
getAndCheckRange(month, 12,   0, "month");
getAndCheckRange(year,  9999, 0, "year");  // Note this corrects for the 0 problem
                                           // I already mentioned.
\$\endgroup\$
3
\$\begingroup\$

Your code could use a lot of work, but it should be easier to clean up the algorithmic things after getting the language cleaned up. I'll go after the "obvious" things for now, which is still a good start.

  • Try not to use using namespace std.

  • days_in_months[], reg_year, and leap_year should be consts and optionally defined above main(). This will protect them from any accidental changes throughout the program.

  • Prefer "\n" over std::endl when only a newline is needed. std::endl also flushes the buffer, which takes longer.

    std::cout << "This printing does three newlines\n\n\n";
    

    std::cout << "This printing does a newline and a flush" << std::endl;
    
  • Prefer to declare/initialize variables as close in scope as possible:

    std::cout << "Message: ";
    int input;
    std::cin >> input;
    
  • cin.ignore() is redundant if you'll be terminating right away. Just get rid of all of them.

  • I strongly recommend using functions. Cramming everything into main() just makes the code hard to read and maintain, especially for a program like this. Consider giving the years, months, and days their own functions. You may also put recurring executions into their own functions (one task per function), while also avoiding creating functions that just display a message.

    For now, you could do that and move all this code into the appropriate functions. The more organized you make your existing code, the easier it will be to refactor all those fors and ifs.

  • Considering adding comments to explain what the code is supposed to do. No need to comment obvious operations such as receiving an input. Only comment where explanation is needed. Adding comments for the ifs and fors could especially help others understand what it's doing.

\$\endgroup\$
0
\$\begingroup\$

(This question smells like a homework assignment, so the follow review comment likely isn't applicable. Anyway...)

This code looks like it is going to implement the date difference calculation. I would't do that. Instead, I'd use your favorite date library/operating system call to parse the user's input. Then, using the same library, I'd compute the difference for output.

Time and date computations are really hard to get right. For example, the year 1900 wasn't a leap year, but both 2000 and 2004 were. Such a library would also--probably--deal with computing the difference both ways. On 1999-12-31, there were -1 days since 2000-1-1.

\$\endgroup\$
  • \$\begingroup\$ Yes date libraries are hard but not for the reason you state. The leap year problem is trivial. 4 Yes 100 No 400 Yes. And the above code has already taken that into account. \$\endgroup\$ – Martin York Nov 15 '13 at 14:39
  • 2
    \$\begingroup\$ Additionally this site is for review. You are supposed to review the code not fix the issues. So perfectly good site for getting a second look at your home work (since we tend to rip things apart). \$\endgroup\$ – Martin York Nov 15 '13 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.