Today's post is an XQuery function designed to get a count of the number of week (or work) days between two dates. It's designed to mimic the Excel NETWORKDAYS
function. I got the algorithm from Bernal Schooley in this thread and then adapted it to XQuery. It also makes use of the FunctX day-of-week
function, so if you have FunctX functions already referenced you can take that part out.
declare namespace functx = "http://www.functx.com"; declare function functx:day-of-week ($date as xs:anyAtomicType?) as xs:integer? { if (empty($date)) then () else xs:integer((xs:date($date) - xs:date('1901-01-06')) div xs:dayTimeDuration('P1D')) mod 7 }; declare function local:weekdays ($start as xs:anyAtomicType?, $end as xs:anyAtomicType?) as xs:integer? { if(empty($start) or empty($end)) then() else if($start > $end) then -local:weekdays($end, $start) else let $dayOfWeekStart := functx:day-of-week($start) let $dayOfWeekEnd := functx:day-of-week($end) let $adjDayOfWeekStart := if($dayOfWeekStart = 0) then 7 else $dayOfWeekStart let $adjDayOfWeekEnd := if($dayOfWeekEnd = 0) then 7 else $dayOfWeekEnd return if($adjDayOfWeekStart <= $adjDayOfWeekEnd) then xs:integer((xs:integer(days-from-duration(xs:date($end) - xs:date($start)) div 7) * 5) + max(((min((($adjDayOfWeekEnd + 1), 6)) - $adjDayOfWeekStart), 0))) else xs:integer((xs:integer(days-from-duration(xs:date($end) - xs:date($start)) div 7) * 5) + min((($adjDayOfWeekEnd + 6) - min(($adjDayOfWeekStart, 6)), 5))) };
Usage: local:weekdays('2009-06-01', '2010-06-30')