Sommer- / Winterzeit prüfen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Knollo
User
Beiträge: 63
Registriert: Mittwoch 10. Juni 2020, 14:44

Hallo in die Runde, ich muss prüfen ob ein Termin in der Sommer- oder Winterzeit liegt und hab dazu das kleine Script geschrieben:

Code: Alles auswählen

from PySide6.QtCore import QDateTime, QDate


def summer_winter_time(date):
    years = date.year()
    first_day = QDate(date.year(),1,1)

    # Sommerzeitumstellung:
    for i in range(31,25, -1):
        summer_date = QDate(years,3,i)
        if summer_date.dayOfWeek()==7:
            break
    days_to_summer = first_day.daysTo(summer_date)

    # Winterzeitumstellung:
    for i in range(31,25, -1):
        winter_date = QDate(years,10,i)
        if winter_date.dayOfWeek()==7:
            break
    days_to_winter = first_day.daysTo(winter_date)

    days_to_date = first_day.daysTo(date)
    if days_to_date > days_to_summer and days_to_date < days_to_winter:
        print("Sommerzeit")
    else:
        print("Winterzeit")
        
if __name__ == "__main__":
    date = QDate.fromString("2025-02-12" ,"yyyy-MM-dd")
    summer_winter_time(date)
Das läuft auch soweit, ich muss nur noch die Uhrzeit einbinden - ABER: geht's auch einfacher?

Danke - Stefan
Sirius3
User
Beiträge: 18250
Registriert: Sonntag 21. Oktober 2012, 17:20

Das ist nicht nur kompliziert sondern auch falsch. Wann welche Zeitumstellungen nötig sind, wird in Datenbanken gespeichert, weil es keine einfachen Regeln dafür gibt.

Code: Alles auswählen

from zoneinfo import ZoneInfo

ZONE_INFO = ZoneInfo("Europe/Berlin")
DAYLIGHT_SECONDS_TO_NAME = {
    0: "Winterzeit",
    3600: "Sommerzeit",
}

def get_daylight_name(datetime):
    return DAYLIGHT_SECONDS_TO_NAME[ZONE_INFO.dst(datetime).seconds]
Knollo
User
Beiträge: 63
Registriert: Mittwoch 10. Juni 2020, 14:44

Hallo, läuft so:

Code: Alles auswählen

        
if __name__ == "__main__":
    date = datetime.strptime("2025-11-12" ,"%Y-%m-%d")
    print(get_daylight_name(date))
ich hatte mich an der Ansage orientiert:
Bild

...aber Dein Script ist wohl die bessere Lösung und läuft...
Danke
Sirius3
User
Beiträge: 18250
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn man wirklich die aktuell gültige Definition benutzen möchte:

Code: Alles auswählen

from datetime import datetime as DateTime, timedelta as TimeDelta

def daylight_saving(datetime):
    last_of_march = DateTime(datetime.year,3,31,2,0)
    delta_days = (last_of_march.weekday() + 1) % 6
    start_summer_time = last_of_march - TimeDelta(days=delta_days)

    last_of_october = DateTime(datetime.year,10,31,3,0)
    delta_days = (last_of_october.weekday() + 1) % 6
    end_summer_time = last_of_october - TimeDelta(days=delta_days)
    return start_summer_time <= datetime <= end_summer_time
Die Gesetzeslage kann sich aber jederzeit ändern, und für die Vergangenheit war sie auch nicht immer gültig.

Das Problem ergibt sich aber gar nicht, weil man für alles, was mit Datum zu tun hat, konsequent mit Zeitzonen arbeiten sollte. Und dann erkennt man an der Differenz des UTC-Offsets zum normalen Offest, ob man Sommerzeit hat, oder nicht.

Code: Alles auswählen

from datetime import datetime as DateTime
from zoneinfo import ZoneInfo

ZONE_INFO = ZoneInfo("Europe/Berlin")


def main():
    date1 = DateTime(2025, 3, 30, 4, 0, tzinfo=ZONE_INFO)
    date2 = DateTime(2025, 3, 30, 1, 0, tzinfo=ZONE_INFO)
    print(date1.utcoffset())  # 7200
    print(date2.utcoffset())  # 3600


if __name__ == "__main__":
    main()
Benutzeravatar
__blackjack__
User
Beiträge: 13998
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Oder man schaut sich das Ergebnis der `dst()`-Methode an ob das 0 ist oder nicht. Dann muss man nicht wissen welcher Wert der ”normale” für die Zeitzone ist.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Knollo
User
Beiträge: 63
Registriert: Mittwoch 10. Juni 2020, 14:44

Danke für die ausführliche Antwort / Erklärung.
Stefan
Benutzeravatar
__blackjack__
User
Beiträge: 13998
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Knollo: Zum Code im ersten Beitrag: `years` sollte `year` heissen und dann auch überall verwendet werden.

Das ermitteln vom letzten Sonntag steht zweimal im Code, das bietet sich für eine eigene Funktion an.

Ungetestet:

Code: Alles auswählen

def get_last_sunday(year, month):
    for day in reversed(range(1, 32)):
        date = QDate(year, month, day)
        if date.dayOfWeek() == 7:
            return date

    assert False, "no sunday should not happen"


# Oder:


def get_last_sunday(year, month):
    dates = (QDate(year, month, day) for day in reversed(range(1, 32)))
    return next(date for date in dates if date.dayOfWeek() == 7)


def print_summer_winter_time(date):
    first_day = QDate(date.year(), 1, 1)
    days_to_summer = first_day.daysTo(get_last_sunday(date.year(), 3))
    days_to_winter = first_day.daysTo(get_last_sunday(date.year(), 10))
    days_to_date = first_day.daysTo(date)
    print(
        "Sommerzeit"
        if days_to_summer <= days_to_date < days_to_winter
        else "Winterzeit"
    )
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Knollo
User
Beiträge: 63
Registriert: Mittwoch 10. Juni 2020, 14:44

hab grad noch 'ne Lösung gefunden:

Code: Alles auswählen

from PySide6.QtCore import QDateTime

date_1 = QDateTime.fromString("2025-03-30 01:00:00" ,"yyyy-MM-dd hh:mm:ss")
print(date_1.timeZoneAbbreviation())# Mitteleuropäische Zeit
date_2 = QDateTime.fromString("2025-03-30 04:00:00" ,"yyyy-MM-dd hh:mm:ss")
print(date_2.timeZoneAbbreviation())# Mitteleuropäische Sommerzeit
nun ja, das entspricht wohl fast dem Ergebnis der `dst()`-Methode.

Danke - Stefan
Antworten