Jump to content

DateDiff_WorkDaysOnly


Go to solution Solved by Gianni,

Recommended Posts

Posted (edited)

Thought I'd share this snippet I created based off jdelaney's post

Calculates date in the past based off of only work days (ie: a week of just workdays).  Any feedback welcome :)

$start_date = "2023/03/27"
$weekdays_ago = 2

$date = DateDiff_WeekDaysOnly($start_date, $weekdays_ago)

Func DateDiff_WeekDaysOnly($start_date, $weekdays_ago)

    $weekdays = 0
    $days_reduce = 0

    While $weekdays <> $weekdays_ago
        $days_reduce -= 1

        $running_date = _DateAdd("d", $days_reduce, $start_date)
        $aTemp = StringSplit($running_date, "/")
        $iDate = _DateToDayOfWeek($aTemp[1], $aTemp[2], $aTemp[3])

        If $iDate <> 1 And $iDate <> 7 Then
            $weekdays += 1
        EndIf
    WEnd

    $date_desired = _DateAdd("d", $days_reduce, $start_date)

    Return $date_desired

EndFunc   ;==>DateDiff_WeekDaysOnly

 

Edited by gcue
Posted

You could also implement the ability to calculate future dates, and also add another parameter to be able to indicate non-working days as you like (e.g. if someone works only Monday, Friday and Sunday he could pass '3,4,5,7' as holidays (assuming 1=Sunday, 2 =Monday , 3=Tuesday, 4=Wednesday, 5=Thursday, 6=Friday, 7=Saturday)
For fun, I wrote a function that has these possibilities using SQL (sqlite), but in order not to hijack your topic, for those interested, I post it in the session dedicated to SQL at this link: https://www.autoitscript.com/forum/topic/210024-a-workday-function-using-sqlite/

 

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Posted (edited)

Instead of counting every single days, it would be faster and somewhat more elegant to divide the number of working days into weeks and then only count the remaining few days :

#include <Date.au3>

Local $sDate = FastWorkDays(_NowDate(), -21)
ConsoleWrite($sDate & @CRLF)

Func FastWorkDays($sDate, $iNumDay)
  If Not $iNumDay Then Return SetError(1)
  Local $iSign = $iNumDay < 0 ? -1 : 1
  Local $iNumWeek = Int(($iNumDay - $iSign) / 5)
  $iNumDay = Mod($iNumDay - $iSign, 5) + $iSign
  $sDate = _DateAdd("w", $iNumWeek, $sDate)
  Local $aTemp, $iDate
  While $iNumDay
    $sDate = _DateAdd("d", $iSign, $sDate)
    $aTemp = StringSplit($sDate, "/")
    $iDate = _DateToDayOfWeek($aTemp[1], $aTemp[2], $aTemp[3])
    If $iDate = "1" Or $iDate = "7" Then ContinueLoop
    $iNumDay -= $iSign
  WEnd
  Return $sDate
EndFunc

:)

Edited by Nine
Posted
On 4/8/2023 at 2:20 PM, Nine said:

Instead of counting every single days, it would be faster and somewhat more elegant to divide the number of working days into weeks and then only count the remaining few days :

#include <Date.au3>

Local $sDate = FastWorkDays(_NowDate(), -21)
ConsoleWrite($sDate & @CRLF)

Func FastWorkDays($sDate, $iNumDay)
  If Not $iNumDay Then Return SetError(1)
  Local $iSign = $iNumDay < 0 ? -1 : 1
  Local $iNumWeek = Floor(($iNumDay - $iSign) / 5)
  $iNumDay = Mod($iNumDay - $iSign, 5) + $iSign
  $sDate = _DateAdd("w", $iNumWeek, $sDate)
  Local $aTemp, $iDate
  While $iNumDay
    $sDate = _DateAdd("d", $iSign, $sDate)
    $aTemp = StringSplit($sDate, "/")
    $iDate = _DateToDayOfWeek($aTemp[1], $aTemp[2], $aTemp[3])
    If $iDate = "1" Or $iDate = "7" Then ContinueLoop
    $iNumDay -= $iSign
  WEnd
  Return $sDate
EndFunc

:)

Hi @Nine
if i'm not doing something wrong, there seems to be a bug there:
tried with FastWorkDays('2023/04/10', -2)
got 2023/03/30 instead of 2023/04/06

p.s.
also, since _NowDate() is localized, better to use _NowCalcDate

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Posted (edited)

@Gianni  You are right, Floor is not working as I expected on negative numbers.  Thanks for testing (It seems I didn't test enough).  Replacing it with Int solves the problem.  Previous code corrected.

Edited by Nine

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...