Click here to Skip to main content
15,889,266 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
This is a code for calculating last Friday of every month from 1970 - 2037. The problem is that from 1970 - 2000 shorts the date by one day. But from 2001 - 2037 is good. Please help me and figure out the problem.

What I have tried:

C++
#include <iostream>
using namespace std;

class lastFriday
{
    int lastDay[12];  //to store last day of all month//хранить последний день всего месяца
    int year; //for given year//за данный год
    string m[12];  // to store names of all 12 months//хранить имя всех 12 месяцев
    bool isleap;  // to check given year is leap year or not//проверить, является ли год високосным или нет
 private:
    //function to find leap year//функция поиска високосного года
    void isleapyear()
    {
        if ((year % 4))
        {
            if (year % 100)
                isleap = true;
            else if ((year % 400))
                isleap = true;
        }
    }

    // to display last  friday of each month
    void display()
    {
        for (int x = 0; x < 12; x++)
            cout << m[x] << lastDay[x] << endl;
    }

    //function to find last friday for a given month 
    int getWeekDay(int m, int d)
    {
        int y = year;

        int f = y + d + 3 * m - 1;
        m++;
        if (m < 3)
            y--;
        else
            f -= int(.4 * m + 2.3);

        f += int(y / 4) - int((y / 100 + 7) * 0.75);
        f %= 7;

        return f;
    }
 public:
    //set name of 12 months
    lastFriday()
    {
        m[0] = "JANUARY:   "; m[1] = "FEBRUARY:  "; m[2] = "MARCH:     "; m[3] = "APRIL:     ";
        m[4] = "MAY:       "; m[5] = "JUNE:      "; m[6] = "JULY:      "; m[7] = "AUGUST:    ";
        m[8] = "SEPTEMBER: "; m[9] = "OCTOBER:   "; m[10] = "NOVEMBER:  "; m[11] = "DECEMBER:  ";
    }

    //function to find last fridays
    void findLastFriday(int y)
    {
        year = y;

        //to check given year is leap year or not
        isleapyear();

        //if given year is leap year then feb has 28 else 29 
        int days[] = { 31, isleap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };  // to set number of days for each month
        int d;

        //for all 12 months we have to find last friday
        for (int i = 0; i < 12; i++)
        {
            d = days[i];
            while (true)
            {
                if (!getWeekDay(i, d))
                    break;
                d--;
            }
            lastDay[i] = d;
        }

        //function call to print display dates of last friday for each month
        display();
    }
};

int main()
{
    int year;  //to store year given by user
    lastFriday LF;

    cout << "Enter the year in the range 1970 to 2037 : ";
    cin >> year;

    //validation for year between 1970 to 2037 
    if (year>2037|year<1970)
    {
        cout << "Not available for this year";
    }
    else
    {
        LF.findLastFriday(year);
    }

    return 0;
}
Posted
Updated 22-Dec-20 22:36pm
v2
Comments
KarstenK 23-Dec-20 4:37am    
tip: write some test code to easier check your code.

The first thing to notice is that any year which is divisible by 400 is automatically divisible by 100. So the second condition will never be executed:
C++
if (year % 100)
    isleap = true;
else if ((year % 400))
    isleap = true;

The second thing to notice is that in C - and by extension in C++ - a zero value is false, and any non-zero value is true. So for x % 4 there will be 3 true values, and one false value.
In addition, you never set isleap to anything other than true anyway ...

Seriously, if that code works at all I'd be surprised - I suspect you tested a single value (or very select values) to see if it worked, and the whole thing is miles out.

Two things I'd strongly recommend:
1) Don't use "global variables" to pass and return values: return a bool value directly from the function instead:
C++
bool IsLeapYear(int year)
   {
   ...
   }

2) Learn to use the debugger - it will save you huge amounts of time when your code doesn't do what you expected it to!
 
Share this answer
 
You should probably note where you got the formula from to calculate the day of the week, but I think this is it Math Forum - Ask Dr. Math[^]

Check your calculations against this and see where you might be going wrong. In particular, note the VERY IMPORTANT message about January and February.

A couple of other notes:
* your test for a leap year is wrong if( (year % 4) ) returns non-zero (true) for any non-leap year. Similarly for testing if its a leap century or not. Note that 2000 was a leap year, and you are only working in the range 1970 - 2038, so the leap century calculation is not needed, but you should probably add a comment to that effect if you decide to remove the test before handing in your assignment so whoever marks it knows that you know why it was OK not to do it
* to test for a valid year, you use year > 2038 | year < 1970) the | is a bitwise or operator. It works here because the two sizes produce only true (1) or false (0), but that might not always be the case. You should use the logical or operatore ||, insteaad.
 
Share this answer
 
I think your logic for detecting a leap year is wrong. The rule is years divisible by 100 are not leap years unless it is divisible by 400. This means the years 1600, 2000, and 2400 are leap years while 1700, 1800, 1900, 2100, 2200, and 2300 are not. That function could be :
C++
bool IsLeapYear( int year )
{
    if( year % 4 )
        return false;   // not divisible by four

    if( year % 100 )
        return true;    // not divisible by 100

    // return true only if evenly divisible by 400

    return ( year % 400 ) == 0;
}
Remember the modulus operator returns 0 if the value divides evenly. If the result of the modulus is non-zero then the value does not divide evenly.
 
Share this answer
 
v2
You sure it's working for 2001-2037? I suspect, there would be issue related to leap years.

Logic wise, to determine whether a year is a leap year, follow these steps:

1. If the year is evenly divisible by 4, go to step 2. Otherwise, go to step 5.
2. If the year is evenly divisible by 100, go to step 3. Otherwise, go to step 4.
3. If the year is evenly divisible by 400, go to step 4. Otherwise, go to step 5.
4. The year is a leap year (it has 366 days).
5. The year is not a leap year (it has 365 days).

Your code seems to be doing different:
C#
//function to find leap year//функция поиска високосного года
void isleapyear()
{

    if ((year % 4))
    {
        if (year % 100)
            isleap = true;
        else if ((year % 400))
            isleap = true;
    }
}

In other words,
if year is divisible by 400 then is_leap_year
else if year is divisible by 100 then not_leap_year
else if year is divisible by 4 then is_leap_year
else not_leap_year

Leads to:
C++
bool isleapyear(int year)
{
     
    // Return true if year is a multiple
    // 0f 4 and not multiple of 100.
    // OR year is multiple of 400.
    return (((year % 4 == 0) && (year % 100 != 0)) ||
             (year % 400 == 0));
}
 
Share this answer
 
Quote:
The problem is that from 1970 - 2000 shorts the date by one day. But from 2001 - 2037 is good.

First idea: something goes wrong with leap year of quad century.
C++
void isleapyear()
{

    if ((year % 4))
    {
        if (year % 100)
            isleap = true;
        else if ((year % 400))
            isleap = true;
    }
}

First question: do you initialize or set isleap to false somewhere ?
Then rethink about the logic: you have code to say that century year is leap and then you have code to ensure that quad century (which is already century) is also leap. You should be shocked by this.
You should reread rules about leap years.
-----
Your code do not behave the way you expect, or you don't understand why !

There is an almost universal solution: Run your code on debugger step by step, inspect variables.
The debugger is here to show you what your code is doing and your task is to compare with what it should do.
There is no magic in the debugger, it don't know what your code is supposed to do, it don't find bugs, it just help you to by showing you what is going on. When the code don't do what is expected, you are close to a bug.
To see what your code is doing: Just set a breakpoint and see your code performing, the debugger allow you to execute lines 1 by 1 and to inspect variables as it execute.

Debugger - Wikipedia, the free encyclopedia[^]

Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[^]
Basic Debugging with Visual Studio 2010 - YouTube[^]

1.11 — Debugging your program (stepping and breakpoints) | Learn C++[^]

The debugger is here to only show you what your code is doing and your task is to compare with what it should do.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900