COSC 1315 - Fundamentals of Programming
Allan Kochis

  1. We want to write a program that inputs a month day and year and tells us what day of the week it is.

  2. Valid Year
    Our year must be greater than 1752 since our calendar changed. So 1752 is an anonmly and before that we would need a different algorithm. For the curious here is what the calendar for 1752 looked like:
                                   1752
    
           January               February                 March
    Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
              1  2  3  4                      1    1  2  3  4  5  6  7
     5  6  7  8  9 10 11    2  3  4  5  6  7  8    8  9 10 11 12 13 14
    12 13 14 15 16 17 18    9 10 11 12 13 14 15   15 16 17 18 19 20 21
    19 20 21 22 23 24 25   16 17 18 19 20 21 22   22 23 24 25 26 27 28
    26 27 28 29 30 31      23 24 25 26 27 28 29   29 30 31
    
            April                   May                   June
    Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
              1  2  3  4                   1  2       1  2  3  4  5  6
     5  6  7  8  9 10 11    3  4  5  6  7  8  9    7  8  9 10 11 12 13
    12 13 14 15 16 17 18   10 11 12 13 14 15 16   14 15 16 17 18 19 20
    19 20 21 22 23 24 25   17 18 19 20 21 22 23   21 22 23 24 25 26 27
    26 27 28 29 30         24 25 26 27 28 29 30   28 29 30
                           31
            July                  August                September
    Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
              1  2  3  4                      1          1  2 14 15 16
     5  6  7  8  9 10 11    2  3  4  5  6  7  8   17 18 19 20 21 22 23
    12 13 14 15 16 17 18    9 10 11 12 13 14 15   24 25 26 27 28 29 30
    19 20 21 22 23 24 25   16 17 18 19 20 21 22
    26 27 28 29 30 31      23 24 25 26 27 28 29
                           30 31
           October               November               December
    Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
     1  2  3  4  5  6  7             1  2  3  4                   1  2
     8  9 10 11 12 13 14    5  6  7  8  9 10 11    3  4  5  6  7  8  9
    15 16 17 18 19 20 21   12 13 14 15 16 17 18   10 11 12 13 14 15 16
    22 23 24 25 26 27 28   19 20 21 22 23 24 25   17 18 19 20 21 22 23
    29 30 31               26 27 28 29 30         24 25 26 27 28 29 30
                                                  31
    


  3. Valid Month
    Between 1 and 12.

  4. Valid Day
    Between 1 and the maximum for that month.
    So 1..31 for January, March, May, July, August, October and December.
    1..30 for April, June, September and November
    February is either 1 .. 28 or 29 depending if it is a leap year.

  5. Leap Year
    A year that is divisible by 4. But it it is divisible by 100, it must be divisible by 400. So
    year divisible
    by 4
    divisible
    by 100
    divisible
    by 400
    Leap
    2006 No - - No
    2004 Yes No - Yes
    1900 Yes Yes No No
    2000 Yes Yes Yes Yes

    If we invert the year divisble by 100 test it looks like a logical or condition. so our test looks like:
    year Y%4 ==0 Y%100 > 0 Y%400 == 0 Leap
    2006 F - - F
    2004 T T - T
    1900 T F F F
    2000 T F T T

  6. Zeller's Congruence.
    To calculate the day of the week for a given date, Zeller's congruence can be applied. A date is expressed as follows: The congruence is

    f={[2.6m-0.2]+k+D+[D/4]+[C/4]-2C} mod 7

    [] denotes the greatest integer in.

  7. Flowcharts








  8. C++ code

    //
    // what day of the week is it?
    //
    #include <iostream>
    
    using namespace std;
    int main()
    {
        int   iMonth, iDay, iYear;  //  input
        bool  bValid=true;          //  valid input flag
        int   iMaxdays;             //  Days in month
        //
        //  variables for Zellers
        //
        int m,k,C,D,f;  //  as in the write up
    
        //
        //  get input
        //
        cout << "Please enter the Month :";
        cin  >> iMonth;
        cout << "Enter the day of the month :";
        cin  >> iDay;
        cout << "Finally enter the year : ";  
        cin  >> iYear;
        //
        //  validate the input
        // 
        if(iMonth <= 1 || iMonth > 12) {
                  cout << "Invalid Month " <<endl;
                  cout << " Must be 1..12" <<endl;
                  bValid=false;
        }
        if(iYear < 1753 ) {
                 cout << "Invalid year " <<endl;
                 cout << "must be greater than 1753 " << endl;
                 bValid=false;
        }
        switch(iMonth) {
            case  1:
            case  3:
            case  5:
            case  7:
            case  8:
            case 10:
            case 12:    iMaxdays=31;
                        break;
            case  4:
            case  6:
            case  9:
            case 11:    iMaxdays=30;
                        break;
            case  2:    if(iYear%4 == 0 &&
                        (iYear%100 >0 || iYear%400 == 0))
                             iMaxdays=29;
                         else iMaxdays=28;
                         break;
            default:    iMaxdays=1;             
        } 
        if(iDay < 1 || iDay > iMaxdays) {
                cout << "Invalid day of Month " << endl;
                cout << "For month " << iMonth 
                     << " must be 1 .. " << iMaxdays << endl;
                 bValid=false;
        }
        //
        // Zeller's congruence
        //
        if(bValid) {
           m=iMonth-2;
           k=iDay; 
           D=iYear;
           if(m <=0) {
               m+=12;
               D--;
           }
           C=D/100;
           D%=100;
           f=((int)(2.6*m-0.2) + k + D + D/4 + C/4 - 2*C) % 7;
           if(f < 0 ) f+=7;   // % to mod fix
           switch(f) {
              case 0 : cout << "Sunday"    << endl; break;
              case 1 : cout << "Monday"    << endl; break;         
              case 2 : cout << "Tuesday"   << endl; break;        
              case 3 : cout << "Wednesday" << endl; break;
              case 4 : cout << "Thursday"  << endl; break;
              case 5 : cout << "Friday"    << endl; break;
              case 6 : cout << "Saturday"  << endl; break;
           }
        } 
           
        
        system("pause");
        return(0);
    }
    

  9. Test cases
    Please enter the Month :9
    Enter the day of the month :27
    Finally enter the year : 2006
    Wednesday
    Press any key to continue . . .                                          
    

    Please enter the Month :12
    Enter the day of the month :7
    Finally enter the year : 1941
    Sunday
    Press any key to continue . . .
    

    Please enter the Month :9
    Enter the day of the month :11
    Finally enter the year : 2001
    Tuesday
    Press any key to continue . . .
    

    Please enter the Month :2
    Enter the day of the month :29
    Finally enter the year : 2006
    Invalid day of Month
    For month 2 must be 1 .. 28
    Press any key to continue . . .
    

    Please enter the Month :13
    Enter the day of the month :23
    Finally enter the year : 1624
    Invalid Month
     Must be 1..12
    Invalid year
    must be greater than 1753
    Invalid day of Month
    For month 13 must be 1 .. 1
    Press any key to continue . . .
    

© Allan Kochis .