Subtract a number of working days from a date

Certified Senior Developer

Is there a function or expression to subtract a number of working days from a date?

caladddays does not accept a negative value and workday does not use the system working calendar so I was hoping there was a simple way to do this (if not I may have to write an expression rule that uses calworkdays and 'tries' several dates until it finds the correct one).

OriginalPostID-181852

OriginalPostID-181852

  Discussion posts and replies are publicly visible

  • 0
    Certified Senior Developer
    But how can I extract a list of holidays from the system working calendar to pass in to the workday function?
  • Adding holidays to the calculation increases complexity, indeed. But then the calculation of the actual result depends on whether you want to move the date to before or after the holidays. You might have to do it in two steps. Get a first date using the workday() function. Now move back or forward until you find a valid date using the calisworkday() function.
  • @Stefanh791 I am stuck in simillar issue. But will the above logic work when the holiday is in between. For example: If I have to find a date 10 business days before today, and there was a holiday 5 days earlier..
  • 0
    Certified Senior Developer
    @atulp Yes the approach should be able to cope with both weekends and holidays occurring within the period you're counting back from. I ended up using two expressions. The first used the workday function to count back a number of days, taking into account weekends, and then it called another expression that used calworkdays to check if, when counting forwards and including holidays, the result returned the original date (or the next workday if the original date was a weekend). This second expression was recursive and called itself if, when counting forwards, the correct date wasn't returned.

    Here's the first expression:
    =with(
    local!startWorkday: caladddays(ri!referenceDate,0),
    local!checkDate: workday(local!startWorkday,-ri!days),
    local!numWorkDays: calworkdays(local!checkDate,local!startWorkday),
    if(
    local!numWorkDays=ri!days+1,
    local!checkDate,
    rule!IWTCIS_getDateByCalWorkdays(ri!referenceDate,local!checkDate,ri!days)
    )
    )

    And here's the second:
    =if(
    /* Use caladddays with 0 to ensure we compare with a working day */
    calworkdays(ri!checkDate,caladddays(ri!referenceDate,0))=ri!days+1,
    ri!checkDate,
    rule!IWTCIS_getDateByCalWorkdays(ri!referenceDate,ri!checkDate-1,ri!days)
    )

    This may not meet your needs exactly but should give you a good starting point (it might not be efficient either as it uses recursion but it seemed to work for us and I was nearly going blind from staring at the screen when trying to get this to work so quit trying to optimize it once I got it working).

    Note this relies on the holidays being defined in the system working calendar.