Ist Datum ein Feiertag ?

    • Offizieller Beitrag

    Als Nebenprodukt zu _GetWokDays() entstand _IsHoliday($iYear, $iMon, $iDay).
    Standardmäßig wird auf bundeseinheitliche Feiertage geprüft.
    Rückgabe:
    ist Feiertag - Name des Feiertages
    kein Feiertag - Leerstring
    Datum nicht valid - 0 und Error

    In der Funktion sind auch alle weiteren Tage aus der Feiertags-UDF verfügbar und können bei Bedarf in die Überprüfung einbezogen werden. Ebenso können eigene Daten hinzugefügt werden.

    Edit:
    Änderung: Bei der Eingabe kann jetzt auch das Datum in der Form "JJJJ/MM/TT" übergeben werden im Parameter $iYear, die anderen Parameter werden dann nicht besetzt.

    Edit2:
    Ich habe den Code noch etwas optimiert und die Fehlerabfrage verändert (Falscheingabe soll auch zu Fehler führen - sonst merkt man's ja nicht).

    _IsHoliday( )
    [autoit]

    #include-once
    #include <Date.au3>
    ;===============================================================================
    ; Function Name: _IsHoliday($iYear, $iMon=-1, $iDay=-1)
    ; Description:: Prüft ob übergebenes Datum ein (bundeseinheitlicher) Feiertag ist
    ; Parameter(s): $iYear das Jahr des Datums (ab 1900) ODER
    ; das gesamte Datum als String "JJJJ/MM/TT"
    ; $iMon der Monat des Datums (wenn $iYear kein GesamtDatumString)
    ; $iDay der Tag des Datums (wenn $iYear kein GesamtDatumString)
    ; Requirement(s): #include <Date.au3>
    ; Return Value(s): Erfolg
    ; ist Feiertag - der Name des Feiertags
    ; kein Feiertag - ein Leerstring
    ; Fehler
    ; 0 @error=1 - Datum nicht existent
    ; Note: der Funktion können regionale und eigene Feiertage zugefügt werden
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _IsHoliday($iYear, $iMon=-1, $iDay=-1)
    Local $aDate = StringRegExp($iYear, '(\d{4})/(\d{1,2})/(\d{1,2})', 3)
    If Not @error Then
    $iYear = $aDate[0]
    $iMon = $aDate[1]
    $iDay = $aDate[2]
    EndIf
    If $iYear < 1900 Or $iMon < 1 Or $iMon > 12 Or $iDay < 1 Or $iDay > 31 Then Return SetError(1,0,0)
    $iMon = StringRight('0' & $iMon, 2)
    $iDay = StringRight('0' & $iDay, 2)
    If Not _DateIsValid($iYear & '/' & $iMon & '/' & $iDay) Then Return SetError(1,0,0)
    Local $oHoliday = ObjCreate('Scripting.Dictionary')
    Local $HDays[32][2], $a, $b, $c, $d, $e, $H1, $H2, $N, $M
    Local $Easter, $EasterDate, $EasterDay, $EasterMonth, $PfSoDat
    ; fixe Feiertage bundesweit
    $oHoliday.Add($iYear & "/01/01", "Neujahr")
    $oHoliday.Add($iYear & "/05/01", "Maifeiertag")
    $oHoliday.Add($iYear & "/10/03", "Tag der Deutschen Einheit")
    $oHoliday.Add($iYear & "/12/25", "1. Weihnachtsfeiertag")
    $oHoliday.Add($iYear & "/12/26", "2. Weihnachtsfeiertag")
    ; variable Feiertage bundesweit
    $a = Mod($iYear, 19)
    $b = Mod($iYear, 4)
    $c = Mod($iYear, 7)
    $H1 = Int($iYear / 100)
    $H2 = Int($iYear / 400)
    $N = 4 + $H1 - $H2
    $M = 15 + $H1 - $H2 - Floor (Int((8 * $H1 + 13) / 25))
    $d = Mod((19 * $a + $M), 30)
    $e = Mod((2 * $b + 4 * $c + 6 * $d + $N), 7)
    If $d + $e = 35 Then
    $Easter = 50
    Else
    If $d = 28 And $e = 6 And $a > 10 Then
    $Easter = 49
    Else
    $Easter = 22 + $d + $e
    EndIf
    EndIf
    If $Easter < 32 Then
    $EasterDay = $Easter
    $EasterMonth = "03"
    Else
    $EasterDay = $Easter - 31
    $EasterMonth = "04"
    EndIf
    If $EasterDay < 10 Then
    $EasterDay = "0" & $EasterDay
    EndIf
    $EasterDate = $iYear & "/" & $EasterMonth & "/" & $EasterDay
    $oHoliday.Add(_DateAdd( 'd', -2, $EasterDate) , "Karfreitag")
    $oHoliday.Add($EasterDate , "Ostersonntag")
    $oHoliday.Add(_DateAdd( 'd', 1, $EasterDate) , "Ostermontag")
    $oHoliday.Add(_DateAdd( 'd', 39, $EasterDate) , "Christi Himmelfahrt")
    $oHoliday.Add(_DateAdd( 'd', 49, $EasterDate) , "Pfingstsonntag")
    $PfSoDat = _DateAdd( 'd', 50, $EasterDate)
    $oHoliday.Add($PfSoDat, "Pfingstmontag")
    #region - fixe und variable Feiertage regional <== Bei Bedarf aktivieren
    #cs
    Local $MutterDat, $4AdvDat
    ; Muttertag = 2. Sonntag im Mai ABER wenn Pfingsten = 2.Sonntag im Mai dann ist Muttertag am 1. Sonntag
    ; Der 2. Sonntag kann nur zw. dem 8. u. 14.5. liegen
    For $maitag = 8 To 14
    If _DateToDayOfWeek($iYear, 5, $maitag) = 1 Then
    If $maitag < 10 Then
    $maitag = "0" & $maitag
    EndIf
    $MutterDat = $iYear & "/05/" & $maitag
    If $MutterDat = $PfSoDat Then
    $MutterDat = _DateAdd( 'd', -7, $iYear & "/05/" & $maitag)
    EndIf
    ExitLoop
    EndIf
    Next
    $oHoliday.Add($MutterDat, "Muttertag")
    ; Erntedankfest 1. Sonntag im Oktober (zw. 1. u. 7.10.)
    For $oktobertag = 1 To 7
    If _DateToDayOfWeek($iYear, 10, $oktobertag) = 1 Then
    $oktobertag = "0" & $oktobertag
    $oHoliday.Add($iYear & "/10/" & $oktobertag, "Erntedankfest")
    ExitLoop
    EndIf
    Next
    ; 4.Advent = Sonntag vor 25.12. (zw. 18. u. 24.12.)
    For $deztag = 18 To 24
    If _DateToDayOfWeek($iYear, 12, $deztag) = 1 Then
    $4AdvDat = $iYear & "/12/" & $deztag
    $oHoliday.Add(_DateAdd( 'd', -7, $4AdvDat), "3. Advent")
    $oHoliday.Add(_DateAdd( 'd', -14, $4AdvDat), "2. Advent")
    $oHoliday.Add(_DateAdd( 'd', -21, $4AdvDat), "1. Advent")
    $oHoliday.Add(_DateAdd( 'd', -28, $4AdvDat), "Totensonntag")
    $oHoliday.Add(_DateAdd( 'd', -32, $4AdvDat), "Buß- und Bettag")
    ExitLoop
    EndIf
    Next
    $oHoliday.Add(_DateAdd( 'd', -52, $EasterDate), "Weiberfastnacht")
    $oHoliday.Add(_DateAdd( 'd', -48, $EasterDate), "Rosenmontag")
    $oHoliday.Add(_DateAdd( 'd', -47, $EasterDate), "Fastnacht")
    $oHoliday.Add(_DateAdd( 'd', -46, $EasterDate), "Aschermittwoch")
    $oHoliday.Add(_DateAdd( 'd', -3, $EasterDate), "Gründonnerstag")
    $oHoliday.Add(_DateAdd( 'd', -1, $EasterDate), "Ostersamstag")
    $oHoliday.Add(_DateAdd( 'd', 60, $EasterDate), "Fronleichnam")
    $oHoliday.Add($iYear & "/01/06", "Heilige Drei Könige")
    $oHoliday.Add($iYear & "/02/14", "Valentinstag")
    $oHoliday.Add($iYear & "/10/31", "Reformationstag")
    $oHoliday.Add($iYear & "/11/01", "Allerheiligen")
    $oHoliday.Add($iYear & "/12/24", "Heiligabend")
    $oHoliday.Add($iYear & "/12/31", "Silvester")
    $oHoliday.Add($4AdvDat, "4. Advent")
    ; ######### Hier können weitere eigene Feiertage eingetragen werden #############
    ; $oHoliday.Add('JJJJ/MM/TT', 'Name des Feiertags') <== MUSTER

    [/autoit] [autoit][/autoit] [autoit]

    ; ###############################################################################
    #ce
    #endregion
    If $oHoliday.Exists($iYear & '/' & $iMon & '/' & $iDay) Then
    Return $oHoliday.Item($iYear & '/' & $iMon & '/' & $iDay)
    Else
    Return ''
    EndIf
    EndFunc ;==>_IsHoliday

    [/autoit]
    • Offizieller Beitrag

    Klasse Funktion!
    Aber es gibt noch einen Bug: Wenn ich das Datum als Zahl übergeben _IsHoliday(2009,1,1) wird der Feiertag nicht erkannt. Erst eine Stringübergabe mit führender Null: _IsHoliday(2009, '01', '01') ergibt das Gesuchte.

    Und wäre es nicht sinnvoll die Datumsübergabe im Format YYYY/MM/DD zu gestalten?
    Dann könnte man z.B. direkt mit der Rückgabe von _NowCalcDate arbeiten:

    [autoit]

    _IsHoliday(_NowCalcDate())

    [/autoit]


    oder mit _DateAdd:

    [autoit]

    _IsHoliday(_DateAdd('d', 20, _NowCalcDate()))

    [/autoit]