- Offizieller Beitrag
Hi,
angeregt durch eine Fragestellung im H&U-Forum habe ich mal die folgende Funktion erstellt:
_GetWorkDays($iMon=-1, $iYear=-1, $iRetType=6, $bHoliday=True)
Für den übergebenen Monat des angegebenen Jahres (-1 jeweils aktueller(s) Monat/Jahr) wird in Abhängigkeit des RetTypes (5=Mo-Fr / 6=Mo-Sa / 7=Mo-So) folgendes ermittelt und in einem 2D-Array zurückgegeben:
[0][0]= Anzahl Werktage im Monat
[0][1]= "WeekNr erster Werktag / WeekNr letzter Werktag"
[1][0]= Datum (Tag) des ersten Werktags
[1][1]= Wochentag des ersten Werktags (0=Mo bis 6=So)
[2..UBound-1][0]=weitere Werktage Datum (Tag)
[2..UBound-1][0]=weitere Werktage Wochentag (0=Mo bis 6=So)
Edit:
Habe es nun doch erweitert, sodass die bundeseinheitlichen Feiertage berücksichtigt werden. Der Parameter kann bei Bedarf auf FALSE gesetzt werden.
Die dazu erstellte Funktion: _IsHoliday($iMon, $iYear, $iDay) läßt sich natürlich auch gut für andere Anwendungen nutzen. Falls Feiertag, wird dessen Name zurückgegeben, anderenfalls ein Leerstring.
_GetWorkDays( )
#include-once
#include <Date.au3>
;===============================================================================
; Function Name: _GetWorkDays([$iMon=-1 [, $iYear=-1 [, $iRetType=6 [, $bHoliday=True]]]])
; Description:: Ermittelt alle Werktage eines Monats
; Parameter(s): $iMon Monat (Standard: -1, aktueller Monat)
; $iYear Jahr (Standard: -1, aktuelles Jahr), kleinster Wert: 1900
; $iRetType (5,6,7) Anzahl Werktage ab Mo (Standard: 6)
; $bHoliday True (Standard) berücksichtigt bundeseinheitliche Feiertage
; Requirement(s): #include <Date.au3>
; Return Value(s): 2D-Array
; [0][0]= Anzahl Werktage im Monat, [0][1]= "WeekNr erster Werktag / WeekNr letzter Werktag"
; [1][0]= Datum (Tag) des ersten Werktags,
; [1][1]= Wochentag des ersten Werktags (0=Mo bis 6=So)
; [n..UBound-1][0/1]=weitere Werktage Datum/Wochentag
; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
;===============================================================================
Func _GetWorkDays($iMon=-1, $iYear=-1, $iRetType=6, $bHoliday=True)
If $iMon < 1 Or $iMon > 12 Then $iMon = @MON
If $iYear < 1900 Then $iYear = @YEAR
If $iRetType < 5 Or $iRetType > 7 Then $iRetType = 6
Local $iDaysInMonth = _DateDaysInMonth($iYear, $iMon)
Local $iWeekday, $aOut[1][2] = [[0,'']], $sWNr = ''
Local $sFreeDay = 'N' ; 7 Werktage, ./. frei
If $iRetType = 5 Then ; 5 Wertage, Sa/So frei
$sFreeDay = '5 6'
ElseIf $iRetType = 6 Then ; 6 Werktage, So frei
$sFreeDay = '6'
EndIf
For $i = 1 To $iDaysInMonth
$iWeekday = _DateToDayOfWeekISO($iYear, $iMon, $i)
If StringInStr($sFreeDay, $iWeekday) Then ContinueLoop
If $bHoliday And _IsHoliday($iYear, $iMon, $i) <> '' Then ContinueLoop
$aOut[0][0] += 1
If $aOut[0][0] = 1 Then $sWNr &= _WeekNumberISO($iYear, $iMon, $i)
ReDim $aOut[UBound($aOut)+1][2]
$aOut[UBound($aOut)-1][0] = $i
$aOut[UBound($aOut)-1][1] = $iWeekday
Next
$aOut[0][1] = $sWNr & '/' & _WeekNumberISO($iYear, $iMon, $aOut[UBound($aOut)-1][0])
Return $aOut
EndFunc ;==>_GetWorkDays
Func _IsHoliday($iYear, $iMon, $iDay)
Local $oHoliday = ObjCreate('Scripting.Dictionary')
Local $HDays[32][2], $a, $b, $c, $d, $e, $H1, $H2, $N, $M
Local $Easter, $EasterDate, $EasterDay, $EasterMonth, $RestJahr, $Tempyear
; 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
If $iYear < 1900 Then ; Datumsoperationen nur mgl. wenn > 1900 , Jahr wird konvertiert
$RestJahr = Mod($iYear, 100)
If _DateIsLeapYear($iYear) Then
If $RestJahr < 10 Then
$RestJahr = "0" & $RestJahr
EndIf
$Tempyear = 20 & $RestJahr
Else
If $RestJahr < 10 Then
$RestJahr = "0" & $RestJahr
EndIf
$Tempyear = 19 & $RestJahr
EndIf
$EasterDate = $Tempyear & "/" & $EasterMonth & "/" & $EasterDay
Else
$EasterDate = $iYear & "/" & $EasterMonth & "/" & $EasterDay
EndIf
$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")
$oHoliday.Add(_DateAdd( 'd', 50, $EasterDate) , "Pfingstmontag")
If $oHoliday.Exists($iYear & '/' & $iMon & '/' & $iDay) Then
Return $oHoliday.Item($iYear & '/' & $iMon & '/' & $iDay)
Else
Return ''
EndIf
EndFunc ;==>_IsHoliday