Counting weekdays in Salesforce is something that you see cropping up every now and then and generally speak the same solution gets wheeled out – loop through the days between your two dates and count the number of days that are Saturday or Sunday. This has, ever since I first saw it, frustrated me; it’s ok for small date ranges but for larger ones it starts to become inefficient, wasting code statements left right and centre – and if it’s in a loop, well it’s just not worth thinking about.

I’ve always felt, deep down, that there must be a more efficient way of do this so, returning from a couple of weeks of disconnectedness, I thought that I’d have a go at finding the solution – you know, just to ease myself back into the swing of things!

The solution that I have come up with is available on GitHub and I have to say that I’m not particularly pleased with it. The basic approach I have taken is to use the standard daysBewteen functionality in APEX and then try to calculate the number of weekends in between those dates that I need to take off the total. It sounds like a great idea but I soon ran into difficulties when it came to dates that started or ended on a weekend – in this case it wasn’t just as simple as multiplying the number of weeks by two to get the number of Saturdays and Sundays. In fact I’ve ended up with a fairly horrid if else statement which makes me cringe – a lot. Here have a look but I’m warning you it’s not pretty.

public static Integer weekdaysBetween(Date d1, Date d2){ Date start = min(d1,d2); Date finish = max(d1,d2); Integer daysBetween = start.daysBetween(finish); Integer startDay = dayOfWeek(start); Integer finishDay = dayOfWeek(finish); daysBetween -= Math.round(((daysBetween + startDay - finishDay) / 7) * 2); if(finishDay == 5 && startDay != 5){ if(startDay == 6) daysBetween += 1; else daysBetween -= 1; } else if(finishDay == 6 && startDay != 6){ if(startDay == 5) daysBetween -= 1; else daysBetween -= 2; } else if(startDay == 5 && finishDay != 5 && finishDay != 6){ daysBetween += 1; } else if(startDay == 6 && finishDay != 5 && finishDay != 6){ daysBetween += 2; } return daysBetween; }

As I said it isn’t pretty! It is probably worth pointing out two other non standard functions in that code – the date min/max and the dayOfWeek functions these are both also in the DateExtensions class on GitHub and are available for your pleasure.

As far as the mess of counting weekdays is concerned I’m fairly sure that what I have still isn’t the most efficient method of achieving my goal but for now I’m going to leave it as it is and hope that it’s of some use to someone. Of course if anyone wants to grab hold of it and improve it then that would be great too – hopefully it’s a good start for someone, somewhere.

Having said that it’s not all doom and gloom; whats there does seem to work and passes the test suite that I currently have for it – it’s just not as efficient as I’d like it to be.