How to get the date of the last Friday of month of given year and month in C

1 Answer

0 votes
#include <stdio.h>

/* Simple date structure */
typedef struct {
    int year;
    int month;
    int day;
} Date;

/* Check if a year is leap year */
int is_leap(int y) {
    if (y % 400 == 0) return 1;
    if (y % 100 == 0) return 0;
    return (y % 4 == 0);
}

/* Days in each month */
int days_in_month(int y, int m) {
    static const int mdays[12] =
        {31,28,31,30,31,30,31,31,30,31,30,31};

    if (m == 2 && is_leap(y))
        return 29;

    return mdays[m - 1];
}

/*
    Zeller's congruence:
    Returns:
        0 = Saturday
        1 = Sunday
        2 = Monday
        3 = Tuesday
        4 = Wednesday
        5 = Thursday
        6 = Friday
*/
int weekday_zeller(int y, int m, int d) {
    if (m < 3) {
        m += 12;
        y -= 1;
    }
    int K = y % 100;
    int J = y / 100;

    return (d + (13*(m + 1))/5 + K + K/4 + J/4 + 5*J) % 7;
}

/*
    Convert Zeller to:
    0 = Monday
    1 = Tuesday
    2 = Wednesday
    3 = Thursday
    4 = Friday
    5 = Saturday
    6 = Sunday
*/
int weekday_monday0(int y, int m, int d) {
    int w = weekday_zeller(y, m, d); /* 0=Sat */
    int map[7] = {5, 6, 0, 1, 2, 3, 4};
    
    return map[w];
}

/*
    last_friday_of_month:

    // Build year_month correctly
    // First day of next month: (ym + 1 month) / day{1}
    // Last day of this month
    // Walk backward to Friday
*/
Date last_friday_of_month(int y, int m) {
    Date result;

    /* Last day of this month */
    int last = days_in_month(y, m);

    /* Walk backward to Friday */
    for (int d = last; d >= 1; d--) {
        int w = weekday_monday0(y, m, d);

        /* Friday = 4 */
        if (w == 4) {
            result.year = y;
            result.month = m;
            result.day = d;
            return result;
        }
    }

    /* Should never reach here */
    result.year = y;
    result.month = m;
    result.day = 1;
    
    return result;
}

int main() {
    Date d = last_friday_of_month(2026, 5);

    printf("%d-%d-%d\n", d.year, d.month, d.day);

    d = last_friday_of_month(2026, 6);

    printf("%d-%d-%d\n", d.year, d.month, d.day);

    return 0;
}



/*
run:

2026-5-29
2026-6-26

*/

 



answered 11 hours ago by avibootz
...