#include <stdint.h>

static int last_sunday(int year, int month)
{
    // Zeller’s congruence (modifiziert)
    int m = month;
    int y = year;

    if (m == 1) { m = 13; y--; }
    if (m == 2) { m = 14; y--; }

    int K = y % 100;
    int J = y / 100;

    int h = (1 + (13 * (m + 1)) / 5 + K + K/4 + J/4 + 5*J) % 7;

    // h = Wochentag des 1. des Monats (0=Samstag, 1=Sonntag, ...)
    int weekday_first = ((h + 6) % 7); // 0=Sonntag, 1=Montag, ...

    // Letzter Tag des Monats
    static const int mdays[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
    int days = mdays[month-1];

    // Schaltjahr?
    if (month == 2 && ((year%4==0 && year%100!=0) || (year%400==0)))
        days = 29;

    // Wochentag des letzten Tages
    int weekday_last = (weekday_first + (days - 1)) % 7;

    // Letzter Sonntag
    return days - weekday_last;
}

int is_dst_europe(int year, int month, int day, int hour)
{
    int start = last_sunday(year, 3);   // letzter Sonntag im März
    int end   = last_sunday(year, 10);  // letzter Sonntag im Oktober

    // Vor Beginn der Sommerzeit
    if (month < 3) return 0;
    if (month > 10) return 0;

    // Zwischen April und September immer Sommerzeit
    if (month > 3 && month < 10) return 1;

    // März: Wechsel um 02:00
    if (month == 3) {
        if (day < start) return 0;
        if (day > start) return 1;
        return (hour >= 2); // am Wechseltag ab 02:00 Sommerzeit
    }

    // Oktober: Wechsel um 03:00
    if (month == 10) {
        if (day < end) return 1;
        if (day > end) return 0;
        return (hour < 3); // am Wechseltag bis 03:00 Sommerzeit
    }

    return 0; // sollte nie erreicht werden
}
