Bonjour à tous,

Je cherche à calculer la durée en nombre de jours entre deux dates en excluant les jours du week-end.
En effectuant quelques recherches je suis tombé sur plusieurs blogs/forums comme ici ou ...

J'ai adapté un petit peu car ils considèrent que le début de la semaine c'est le dimanche :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
-- Diff en nb de jours entre deux dates
SELECT DATEDIFF(d, DATE_DEB, DATE_FIN)
       - 2 * (DATEPART(ISO_WEEK,DATE_FIN) - DATEPART(ISO_WEEK,DATE_DEB)) -- Suppression de 2 jours par semaines
       + (CASE WHEN DATEPART(dw, DATE_DEB) = 7 THEN 1 ELSE 0 END) -- Tout evt débutant le dimanche est considéré comme débutant le lundi (idem pour le samedi mais pas d'exception à gérer)
       - (CASE WHEN DATEPART(dw, DATE_FIN) = 7 THEN 1 ELSE 0 END)-- Tout evt terminant le dimanche est considéré comme terminant le lundi (idem pour le samedi mais pas d'exception à gérer)
J'ai effectué quelques tests et, à mon avis, ça ne fonctionne pas.
En effet, il m'arrive de commencer une chose en décembre et de la finir en janvier et comme les numéros des semaines sont remis à zéro en début d'année, la suppression de deux jours par semaines ajoute 104 ou 106 jours selon les cas...

Ci dessous mes cas de tests :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
DECLARE @TABLE TABLE (EVT INT, DATE_DEB DATETIME, DATE_FIN DATETIME)
 
-- Cas simple
INSERT @TABLE SELECT 1, '15/08/2016 09:00:00.000', '16/08/2016 09:00:00.000'
 
-- Cas de changement de semaine
INSERT @TABLE SELECT 2, '05/08/2016 09:00:00.000', '08/08/2016 09:00:00.000'
 
-- Cas de début un samedi
INSERT @TABLE SELECT 3, '06/08/2016 09:00:00.000', '08/08/2016 09:00:00.000'
 
-- Cas de début un dimanche
INSERT @TABLE SELECT 4, '07/08/2016 09:00:00.000', '08/08/2016 09:00:00.000'
 
-- Cas de fin un samedi
INSERT @TABLE SELECT 5, '05/08/2016 09:00:00.000', '06/08/2016 09:00:00.000'
 
-- Cas de fin un dimanche
INSERT @TABLE SELECT 6, '05/08/2016 09:00:00.000', '07/08/2016 09:00:00.000'
 
-- Cas de début un samedi et de fin un dimanche
INSERT @TABLE SELECT 7, '06/08/2016 09:00:00.000', '07/08/2016 09:00:00.000'
 
-- Cas de début un samedi et de fin un samedi
INSERT @TABLE SELECT 8, '06/08/2016 09:00:00.000', '06/08/2016 09:00:00.000'
 
-- Cas de début un dimanche et de fin un dimanche
INSERT @TABLE SELECT 9, '07/08/2016 09:00:00.000', '07/08/2016 09:00:00.000'
 
-- Cas de reset du numéro de semaine
-- le 01/01/2016 nous étions semaine 53 et le 04/01/2016 semaine 1
INSERT @TABLE SELECT 10, '01/01/2016 09:00:00.000', '04/01/2016 09:00:00.000'
 
SELECT EVT,
       DATE_DEB,
       DATE_FIN,
       DATENAME(dw, DATE_DEB) AS JOUR_DEB,
       DATEPART(ISO_WEEK,DATE_DEB) AS SEM_DEB,
       DATENAME(dw, DATE_FIN) AS JOUR_FIN,
       DATEPART(ISO_WEEK,DATE_FIN) AS SEM_FIN,
       -- Diff en nd de jours entre deux dates
       DATEDIFF(d, DATE_DEB, DATE_FIN) -- Suppression de 2 jours par semaines
       - 2 * (DATEPART(ISO_WEEK,DATE_FIN) - DATEPART(ISO_WEEK,DATE_DEB)) -- Tout evt débutant le dimanche est considéré comme débutant le lundi (idem pour le samedi mais pas d'exception à gérer)
       + (CASE WHEN DATEPART(dw, DATE_DEB) = 7 THEN 1 ELSE 0 END) -- Tout evt terminant le dimanche est considéré comme terminant le lundi (idem pour le samedi mais pas d'exception à gérer)
       - (CASE WHEN DATEPART(dw, DATE_FIN) = 7 THEN 1 ELSE 0 END)
       AS DureeJour
FROM   @TABLE
Je me suis peut-être raté dans l'adaptation pour le calendrier français mais il me semble pas que le changement d'année soit géré dans la version originale.

Lorsque j'essaye de le gérer je multiplie les CASE, ça devient illisible et ça ne résout rien...

Est-il possible de gérer le changement d'année à partir de cette méthode de calcul ?
Ou existe-il un autre moyen simple (sans table de référence) pour gérer la durée entre deux dates sans compter les week-end et qui prend en compte le changement d'année ?

Par avance, merci.