2

I have 2 dates and want to know how many weekdays (mon-fri) there are

e.g.

thu jan 1 20xx    
fri jan 2 20xx    
sat jan 3 20xx    
sun jan 4 20xx    
mon jan 5 20xx  

jan 1, jan 5 would return 3

(can ignore public holidays)

adolf garlic
  • 3,034
  • 7
  • 39
  • 54
  • This might help you as well. http://stackoverflow.com/questions/4025047/tsql-function-to-calculate-30-working-days-date-from-a-specified-date-sql-server – Brian Dishaw Jun 21 '11 at 12:41
  • possible duplicate of [Count work days between two dates in T-SQL](http://stackoverflow.com/questions/252519/count-work-days-between-two-dates-in-t-sql) – Mikael Eriksson Jun 21 '11 at 13:31
  • 1
    more than likely - the search in SO is rubbish, I tried loads of variations and nothing came up – adolf garlic Jun 21 '11 at 14:02

6 Answers6

1

Try

 DateDiff(day, @DtA, @DtB) - 2 * DateDiff(Week, @DtA, @DtB)

this may not work exactly, but you can see the idea. Some slight modification will work.

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • This somehow needs to take into account the day of the week and the datediff by conventional means and add 1 to two of the dates under this system. Brain...melting... – adolf garlic Jun 21 '11 at 13:28
1

try this:

SET DATEFIRST 1
DECLARE @StartDate datetime
       ,@EndDate datetime
SELECT @StartDate='6/21/2011'
      ,@EndDate='6/28/2011'
;with AllDates AS
(
    SELECT @StartDate AS DateOf, datepart(weekday,getdate()) AS WeekDayNumber
    UNION ALL
    SELECT DateOf+1, datepart(weekday,DateOf+1)
        FROM AllDates
    WHERE DateOf<@EndDate
)
SELECT COUNT(*) AS WeekDayCount FROM AllDates WHERE WeekDayNumber<=5

OUTPUT:

WeekDayCount
------------
6

(1 row(s) affected)

If you have a holiday table, you can join it in and remove those as well.

EDIT based on @Ross Watson comment:

SET DATEFIRST 1
DECLARE @StartDate datetime
       ,@EndDate datetime
SELECT @StartDate='6/21/2011'
      ,@EndDate='6/28/2011'
;with AllDates AS
(
    SELECT @StartDate AS DateOf, datepart(weekday,getdate()) AS WeekDayNumber
    UNION ALL
    SELECT DateOf+1, (WeekDayNumber+1) % 7
        FROM AllDates
    WHERE DateOf<@EndDate
)
SELECT COUNT(*) AS WeekDayCount FROM AllDates WHERE WeekDayNumber>0 AND WeekDayNumber<6
--I don't like using "BETWEEN", ">", ">=", "<", and "<=" are more explicit in defining end points

produces same output as original query.

KM.
  • 101,727
  • 34
  • 178
  • 212
  • Nice... very nice. I like the recursion. However, you don't need to work out the weekday for anything other than the first day. Just keep adding 1 and take modulo 7. So... "SELECT DateOf+1, (WeekDayNumber+1) % 7" and the final select is "WHERE WeekDayNumber between 1 and 5" – Black Light Jun 21 '11 at 13:44
  • this does not work for certain date ranges. check the weekday count. the weekdaynumbers are not consistent depending on the start date. – jlo-gmail Jan 28 '16 at 19:29
1

Assuming the dates can't be more than five and a half years from each other (or use your own tally table instead of master..spt_values):

DECLARE @date1 datetime, @date2 datetime;
SET @date1 = '20110901';
SET @date2 = '20110905';

SELECT COUNT(*)
FROM (
  SELECT
    Date = DATEADD(day, number, @date1)
  FROM master..spt_values
  WHERE type = 'P'
    AND number between 0 AND DATEDIFF(day, @date1, @date2)
) s
WHERE DATENAME(DW, Date) NOT IN ('Saturday', 'Sunday')
Andriy M
  • 76,112
  • 17
  • 94
  • 154
0

This approach is limited to ~100 days due to recursion. This works for the date ranges i've tested. Same idea above, removed the math and simplified:

BEGIN
    SET DATEFIRST 1
    DECLARE @StartDate datetime
           ,@EndDate datetime
    SELECT @StartDate='12/16/2015'
          ,@EndDate='1/8/2016'
    ;with AllDates AS
    (
        SELECT @StartDate AS DateOf 
        UNION ALL
        SELECT DateOf+1 
            FROM AllDates
        WHERE DateOf<@EndDate
    )
    SELECT COUNT(*) AS WeekDayCount 
        FROM 
        AllDates 
    WHERE 
        datepart(weekday,DateOf) between 1 AND 5

    --SELECT DateOf [date], datepart(weekday,DateOf) [day] 
    --FROM 
    --  AllDates 
    --WHERE 
    --  datepart(weekday,DateOf) between 1 AND 5
END
jlo-gmail
  • 4,453
  • 3
  • 37
  • 64
0

Try the following:

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @StartDate = '2011/06/01'
SET @EndDate = '2011/06/31'

SELECT   
    (DATEDIFF(dd, @StartDate, @EndDate) + 1)  - 
    (DATEDIFF(wk, @StartDate, @EndDate) * 5)  -
    (
        CASE 
           WHEN DATENAME(dw, @StartDate) in 
               ('Sunday', 'Tuesday', 'Wednesday', 'Turesday', 'Saturday') 
           THEN 1 
           ELSE 0 
        END
    )  -
    (
        CASE 
           WHEN DATENAME(dw, @EndDate) in 
               ('Sunday', 'Tuesday', 'Wednesday', 'Turesday', 'Saturday') 
           THEN 1 
           ELSE 0 
        END
    )
Akram Shahda
  • 14,655
  • 4
  • 45
  • 65