• §

    Jonas Altrock ew20b126@technikum-wien.at

    To overview.

    The whole source file u6_weekday.c.

    /* Compile with `clang -std=c99 -Wall -o u6_weekday u6_weekday.c` */
    /* Test with `../checkproject u6_weekday` */
  • §

    Include C-libraries for input/output.

    #include <stdio.h>
    #include <stdlib.h>
  • §

    Exercise 6: Procedures: Day of Week

  • §

    Find the day of week of a given date past the year 1583.

    Details

  • §

    Read a date in the format yyyy-mm-dd (same as Exercise 4) and then print the day of week. Use capitalization, i.e. print the first letter in upper case and the remaining letters in lower case!

    You may assume that the date is always valid and yyyy is larger or equal 1584.

    For this exercise, it is required to use multiple procedures - please, find and implement reasonable functions with their own responsibilities!

    Hints

  • §

    There are many ways to solve this exercise (see for instance Wikipedia - Doomsday Rule. The following is a suggestion how to solve it. You are free to take some of these hints or proposals or to write your own version but it is not allowed to call an inbuilt function that already solves this exercise.

    Split the exercise into multiple smaller exercises

  • §

    Identify useful procedures. The following sketch could help you:

    Count the number of days passed since the first of january 1584 (which was a Sunday).

    • For all years before the entered year find out the number of days passed since (including) the year 1584 (procedure daysBefore(int year))
      • Find out how many days a given year has.
        • Check whether a given year is a leap year (procedure isLeapYear(int year))
    • Find out how many days have passed since the 1st of January of the entered year (= sum of days of passed in previous months)
      • Find out how many days a given month has (procedure daysInMonth)
        • Depends on the year (leap years)!

    From these values you can calculate the number of days passed since the first of january 1584.

    From the number of days passed since the first of january 1584 you can find the day of the week of the entered day using modulo 7. If the result is 0, then the day is a Sunday (because the 1st of january 1584 was a Sunday), if it is 1 a Monday, etc. …

    Make sure that during implementing procedures you check whether they return correct values.

    Remark

  • §

    The year 1584 is picked in this exercise because it is the first year after the introduction of the Gregorian calendar such that the 1st of January is a Sunday.

    Example 1

  • §

    Input:

    2016-8-12
    

    Output:

    Friday
    

    Example 2

  • §

    Input:

    1585-1-1
    

    Output:

    Tuesday
    

    Forward declarations

  • §

    days_since_1584, days_in_month, is_leap_year, day_of_week.

    int days_since_1584(int y, int m, int d);
    int days_in_month(int y, int m);
    int is_leap_year(int y);
    const char *day_of_week(int d);
  • §

    main()

  • §

    Implement the solution by

    int main() {
        int yyyy, mm, dd;
  • §

    reading in the date in the format YYYY-MM-DD,

        scanf("%04d-%02d-%02d", &yyyy, &mm, &dd);
  • §

    calculating the number of days since 1st of January, 1584,

        int days = days_since_1584(yyyy, mm, dd);
  • §

    and then printing the day the week for the given date from that number.

        printf("%s\n", day_of_week(days));
        return 0;
    }
  • §

    days_since_1584()

  • §

    Count days since 1st of January 1584 (which was Sunday).

    int days_since_1584(int y, int m, int d) {
        int days = 0;
  • §

    Loop through years before the given year, and sum their days.

        for (int i = 1584; i < y; i++) {
            if (is_leap_year(i)) {
                days += 366;
            } else {
                days += 365;
            }
        }
  • §

    Loop through months in the given year, and sum their days.

        for (int j = 1; j < m; j++) {
            days += days_in_month(y, j);
        }
  • §

    Finally add the days in the given month (-1 because jan 1st is the reference date).

        days += d - 1;
  • §

    Return the total number of days.

        return days;
    }
  • §

    is_leap_year()

  • §

    Check if a given year is a leap year. Returns 1 or 0.

    int is_leap_year(int y) {
  • §

    Leap years must be divisible by 4.

        if (y % 4 != 0) return 0;
  • §

    Not a leap year if divisible by 100, except if divisible by 400.

        if (y % 100 == 0 && y % 400 != 0) return 0;
  • §

    Otherwise, a leap year.

        return 1;
    }
  • §

    days_in_month()

  • §

    Get the number of days in a given month of a given year. Takes into account that February has 29 days in a leap year.

    int days_in_month(int y, int m) {
        if (m == 1) return 31;
        if (m == 2) return 28 + is_leap_year(y);
        if (m == 3) return 31;
        if (m == 4) return 30;
        if (m == 5) return 31;
        if (m == 6) return 30;
        if (m == 7) return 31;
        if (m == 8) return 31;
        if (m == 9) return 30;
        if (m == 10) return 31;
        if (m == 11) return 30;
        if (m == 12) return 31;
        return 0; // *shrug*
    }
  • §

    day_of_week()

  • §

    Get the name of the day in the week. Argument is the number of days since January 1st, 1584, which was a Sunday.

    const char *day_of_week(int d) {
  • §

    Modulo 7, as the hint suggested.

        d = d % 7;
  • §

    Then give the string constant depending on the result (0 to 6).

        if (d == 0) return "Sunday";
        if (d == 1) return "Monday";
        if (d == 2) return "Tuesday";
        if (d == 3) return "Wednesday";
        if (d == 4) return "Thursday";
        if (d == 5) return "Friday";
        return "Saturday";
    }