#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
*/