_WorkDay() Returns the date that is the specified number of working days before or after the start date
This is a variation of a function from this post that implements more features, namely, the function allows 3 parameters:
$StartDate: Date representing the start date of the count. (no check is made on the correctness of the date provided)
$iDays: Number of working days before or after the start_date. A positive value indicates a future date; a negative value indicates a past date; a zero value indicates the start_date itself. (Indicating 0 the departure date is returned even if this corresponds to a non-working day, but in this case the @error flag is set to 1)
$sHolidays: Optional (default 1,7). Indicate the days of the week considered non-working (not to be considered in the count). $sHolidays represents a string with any combination of digits from 1 to 7 (the comma between the digits is optional) which indicates the days of the week to be considered holidays which correspond as follows: 1=Sunday, 2 =Monday , 3=Tuesday, 4=Wednesday, 5=Thursday, 6=Friday, 7=Saturday. if you want to consider working all days of the week pass an empty string then. (if, by contradiction, all seven days of the week are indicated as holidays, the day pointed to by $Days is returned anyway, but the @error flag is also set to 1)
I hope there are no bugs.
Have fun.
#include <date.au3>
_Example()
; 1=Sunday, 2 =Monday , 3=Tuesday, 4=Wednesday, 5=Thursday, 6=Friday, 7=Saturday
Func _Example()
Local $Start = _NowCalcDate()
Local $count = 25
MsgBox(0, 'example 1', "The " & $count & "th working days past " & $Start & " is " & _WorkDay($Start, $count))
$count = -9
MsgBox(0, 'example 2', $count & " workdays ago: " & _WorkDay($Start, $count))
$Start = "2022/12/31"
$count = 33
$NoCountWeekDays = '234567' ; <-- all holidays except Sunday (count only the Sunday)
MsgBox(0, 'example 3', "The " & $count & "th Sunday of the 2023 is on " & _WorkDay($Start, $count, $NoCountWeekDays))
$Start = _NowCalcDate()
$count = -15 ; negative
$NoCountWeekDays = '134567' ; <-- all holidays except Monday (count only the Monday)
MsgBox(0, 'example 4', $count & " Mondays ago was " & _WorkDay($Start, $count, $NoCountWeekDays))
EndFunc ;==>_Example
; #FUNCTION# ====================================================================================================================
; Name ..........: _WorkDay
; Description ...:
; Syntax ........: _WorkDay([$StartDate = _NowCalcDate([, $iDays = 0[, $sHolidays = "17"]]])
; Parameters ....: $StartDate - Start day.
; $iDays - number of WorkDays to count (positive or negative)
; $sHolidays - a string of digits indicating not working days of week. Default is "17".
; Return values .: Target date
; Author ........: Gianni
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _WorkDay($StartDate = _NowCalcDate(), $iDays = 0, $sHolidays = "17")
Local $iDirection = 1 * ($iDays < 0 ? -1 : $iDays > 0), $iWeekdays = 0
Local $iWorkDays = StringRegExpReplace("1234567", "[" & StringRegExpReplace($sHolidays, "[^1234567]", "") & "]", "")
Local $aYMD = StringSplit($StartDate, "/", 2)
Local $nJulianDate = _DateToDayValue($aYMD[0], $aYMD[1], $aYMD[2])
If Not $iDirection Then Return SetError(False = StringInStr($iWorkDays, _DateToDayOfWeek($aYMD[0], $aYMD[1], $aYMD[2]), 2), 0, $StartDate)
If $iWorkDays = '' Then Return SetError(1, 0, _DateAdd('D', $iDays, $StartDate))
$iDays = Abs($iDays)
Do
$nJulianDate += $iDirection
_DayValueToDate($nJulianDate, $aYMD[0], $aYMD[1], $aYMD[2])
$iWeekdays += (StringInStr($iWorkDays, _DateToDayOfWeek($aYMD[0], $aYMD[1], $aYMD[2]), 2) ? 1 : 0)
Until $iWeekdays = $iDays
Return SetError(0, 0, $aYMD[0] & '/' & $aYMD[1] & '/' & $aYMD[2])
EndFunc ;==>_WorkDay