CALCUL UNE DIFFÉRENCE DE DATE EN FONCTION DE JOURS FÉRIÉS/TRAVAILLÉS ET DE PLAGE
dymsbess
Messages postés56Date d'inscriptionmercredi 29 septembre 2004StatutMembreDernière intervention 4 janvier 2010
-
10 juin 2009 à 09:44
kyaume -
13 déc. 2017 à 16:49
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
Bonjour,
Merci pour la proc stock et les heures de debug qui vont avec
Il faut tenir compte dans le calcul des cas ou la date de fin est hors plage ou un jour non travailler. comme ci-dessous :
USE [PoleHorsSAP]
GO
/****** Object: UserDefinedFunction [dbo].[FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE] Script Date: 01/10/2014 18:52:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE] (@Date1 DATETIME, @Date2 DATETIME)
RETURNS INT AS
BEGIN
DECLARE @DateCreCalcul DATETIME
DECLARE @DateCre2Calcul DATETIME
DECLARE @NbJourneesNonTravaillees INT
DECLARE @NbNuits INT
DECLARE @LSTTEST VARCHAR
DECLARE @LSTTESTT VARCHAR
SET @DateCreCalcul = @Date1
-- Si Date1 inférieure à l'heure d'ouverture
IF DATEPART(hour, @Date1) < 9
BEGIN
SET @DateCreCalcul = DATEADD(hour, - DATEPART(hour, @Date1) + 9, @Date1)
SET @DateCreCalcul = DATEADD(minute, - DATEPART(minute, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(second, - DATEPART(second, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCreCalcul), @DateCreCalcul)
END
-- Si Date2 inférieure à l'heure d'ouverture
IF DATEPART(hour, @Date2) < 9
BEGIN
SET @DateCre2Calcul = DATEADD(hour, - DATEPART(hour, @Date2) + 9, @Date2)
SET @DateCre2Calcul = DATEADD(minute, - DATEPART(minute, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(second, - DATEPART(second, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCre2Calcul), @DateCre2Calcul)
END
-- Si Date1 supérieure à l'heure de fermeture
IF DATEPART(hour, @Date1) >= 18 BEGIN
SET @DateCreCalcul = DATEADD(hour, - DATEPART(hour, @Date1) + 18, @Date1)
SET @DateCreCalcul = DATEADD(minute, - DATEPART(minute, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(second, - DATEPART(second, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCreCalcul), @DateCreCalcul)
END
-- Si Date2 supérieure à l'heure de fermeture
IF DATEPART(hour, @Date2) >= 18 BEGIN
SET @DateCre2Calcul = DATEADD(hour, - DATEPART(hour, @Date2) + 18, @Date2)
SET @DateCre2Calcul = DATEADD(minute, - DATEPART(minute, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(second, - DATEPART(second, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCre2Calcul), @DateCre2Calcul)
END
-- Si Date1 est un dimanche, on ajoute 1 jour et on commence à l'heure d'ouverture
IF DatePart(weekday, @Date1) = 7 BEGIN
SET @DateCreCalcul = DATEADD(day, 1, @DateCreCalcul)
SET @DateCreCalcul = DATEADD(hour, - DATEPART(hour, @DateCreCalcul) + 9, @DateCreCalcul)
SET @DateCreCalcul = DATEADD(minute, - DATEPART(minute, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(second, - DATEPART(second, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCreCalcul), @DateCreCalcul)
END
-- Si Date2 est un dimanche, on ajoute 1 jour et on commence à l'heure d'ouverture
IF DatePart(weekday, @Date2) = 7 BEGIN
SET @DateCre2Calcul = DATEADD(day, 1, @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(hour, - DATEPART(hour, @DateCre2Calcul) + 9, @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(minute, - DATEPART(minute, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(second, - DATEPART(second, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCre2Calcul), @DateCre2Calcul)
END
-- Si Date1 est un samedi, on ajoute 2 jours et on commence à l'heure d'ouverture
IF DatePart(weekday, @Date1) = 6 BEGIN
SET @DateCreCalcul = DATEADD(day, 2, @DateCreCalcul)
SET @DateCreCalcul = DATEADD(hour, - DATEPART(hour, @DateCreCalcul) + 9, @DateCreCalcul)
SET @DateCreCalcul = DATEADD(minute, - DATEPART(minute, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(second, - DATEPART(second, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCreCalcul), @DateCreCalcul)
END
-- Si Date2 est un samedi, on ajoute 2 jours et on commence à l'heure d'ouverture
IF DatePart(weekday, @Date2) = 6 BEGIN
SET @DateCre2Calcul = DATEADD(day, 2, @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(hour, - DATEPART(hour, @DateCre2Calcul) + 9, @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(minute, - DATEPART(minute, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(second, - DATEPART(second, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCre2Calcul), @DateCre2Calcul)
END
SET @NbJourneesNonTravaillees = 0
SET @NbNuits = DATEDIFF(day, @DateCreCalcul, @DateCre2Calcul)
-- Si les 2 dates sont à des jours différents, on cherche le nombre de jours NON travaillés entre les 2 dates
DECLARE @Compteur_NbNuits int;
SET @Compteur_NbNuits = 0;
-- Dans une boucle, on balaye tous les jours entre les 2 dates pour compter le nombre de jours non travaillés
WHILE @Compteur_NbNuits < @NbNuits
BEGIN
SET @Compteur_NbNuits = @Compteur_NbNuits + 1;
SET @LSTTEST = dbo.FN_JourTravailleFerie(DATEADD(day, @Compteur_NbNuits, @DateCreCalcul), 1)
IF @LSTTEST <> 'X'
BEGIN
SET @NbJourneesNonTravaillees = @NbJourneesNonTravaillees + 1
END
END
-- On calcule la différence en minutes et on retire :
-- - la durée des des nuits en minutes
-- - la durée des journées non travaillées en minutes
RETURN datediff(minute, @DateCreCalcul, @DateCre2Calcul) - 900*@NbNuits - 540*@NbJourneesNonTravaillees
END
cs_Sieurcoug
Messages postés10Date d'inscriptionjeudi 26 février 2009StatutMembreDernière intervention16 avril 2012 23 sept. 2010 à 09:54
> Avez vous une estimation sur le temps d'exécution de cette fonction? (pour 1000 dates par exemple)
Ca dépend des ressources...
Pour moi le calcul est très rapide, sur plusieurs centaines, voire millier d'enregistrement.
wajdi0001
Messages postés1Date d'inscriptiondimanche 26 avril 2009StatutMembreDernière intervention22 septembre 2010 22 sept. 2010 à 12:16
Avez vous une estimation sur le temps d'exécution de cette fonction? (pour 1000 dates par exemple)
dymsbess
Messages postés56Date d'inscriptionmercredi 29 septembre 2004StatutMembreDernière intervention 4 janvier 20101 10 juin 2009 à 09:44
13 déc. 2017 à 16:49
Modifié par François le 1/10/2014 à 18:52
Merci pour la proc stock et les heures de debug qui vont avec
Il faut tenir compte dans le calcul des cas ou la date de fin est hors plage ou un jour non travailler. comme ci-dessous :
USE [PoleHorsSAP]
GO
/****** Object: UserDefinedFunction [dbo].[FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE] Script Date: 01/10/2014 18:52:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE] (@Date1 DATETIME, @Date2 DATETIME)
RETURNS INT AS
BEGIN
DECLARE @DateCreCalcul DATETIME
DECLARE @DateCre2Calcul DATETIME
DECLARE @NbJourneesNonTravaillees INT
DECLARE @NbNuits INT
DECLARE @LSTTEST VARCHAR
DECLARE @LSTTESTT VARCHAR
SET @DateCreCalcul = @Date1
-- Si Date1 inférieure à l'heure d'ouverture
IF DATEPART(hour, @Date1) < 9
BEGIN
SET @DateCreCalcul = DATEADD(hour, - DATEPART(hour, @Date1) + 9, @Date1)
SET @DateCreCalcul = DATEADD(minute, - DATEPART(minute, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(second, - DATEPART(second, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCreCalcul), @DateCreCalcul)
END
-- Si Date2 inférieure à l'heure d'ouverture
IF DATEPART(hour, @Date2) < 9
BEGIN
SET @DateCre2Calcul = DATEADD(hour, - DATEPART(hour, @Date2) + 9, @Date2)
SET @DateCre2Calcul = DATEADD(minute, - DATEPART(minute, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(second, - DATEPART(second, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCre2Calcul), @DateCre2Calcul)
END
-- Si Date1 supérieure à l'heure de fermeture
IF DATEPART(hour, @Date1) >= 18 BEGIN
SET @DateCreCalcul = DATEADD(hour, - DATEPART(hour, @Date1) + 18, @Date1)
SET @DateCreCalcul = DATEADD(minute, - DATEPART(minute, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(second, - DATEPART(second, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCreCalcul), @DateCreCalcul)
END
-- Si Date2 supérieure à l'heure de fermeture
IF DATEPART(hour, @Date2) >= 18 BEGIN
SET @DateCre2Calcul = DATEADD(hour, - DATEPART(hour, @Date2) + 18, @Date2)
SET @DateCre2Calcul = DATEADD(minute, - DATEPART(minute, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(second, - DATEPART(second, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCre2Calcul), @DateCre2Calcul)
END
-- Si Date1 est un dimanche, on ajoute 1 jour et on commence à l'heure d'ouverture
IF DatePart(weekday, @Date1) = 7 BEGIN
SET @DateCreCalcul = DATEADD(day, 1, @DateCreCalcul)
SET @DateCreCalcul = DATEADD(hour, - DATEPART(hour, @DateCreCalcul) + 9, @DateCreCalcul)
SET @DateCreCalcul = DATEADD(minute, - DATEPART(minute, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(second, - DATEPART(second, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCreCalcul), @DateCreCalcul)
END
-- Si Date2 est un dimanche, on ajoute 1 jour et on commence à l'heure d'ouverture
IF DatePart(weekday, @Date2) = 7 BEGIN
SET @DateCre2Calcul = DATEADD(day, 1, @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(hour, - DATEPART(hour, @DateCre2Calcul) + 9, @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(minute, - DATEPART(minute, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(second, - DATEPART(second, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCre2Calcul), @DateCre2Calcul)
END
-- Si Date1 est un samedi, on ajoute 2 jours et on commence à l'heure d'ouverture
IF DatePart(weekday, @Date1) = 6 BEGIN
SET @DateCreCalcul = DATEADD(day, 2, @DateCreCalcul)
SET @DateCreCalcul = DATEADD(hour, - DATEPART(hour, @DateCreCalcul) + 9, @DateCreCalcul)
SET @DateCreCalcul = DATEADD(minute, - DATEPART(minute, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(second, - DATEPART(second, @DateCreCalcul), @DateCreCalcul)
SET @DateCreCalcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCreCalcul), @DateCreCalcul)
END
-- Si Date2 est un samedi, on ajoute 2 jours et on commence à l'heure d'ouverture
IF DatePart(weekday, @Date2) = 6 BEGIN
SET @DateCre2Calcul = DATEADD(day, 2, @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(hour, - DATEPART(hour, @DateCre2Calcul) + 9, @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(minute, - DATEPART(minute, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(second, - DATEPART(second, @DateCre2Calcul), @DateCre2Calcul)
SET @DateCre2Calcul = DATEADD(millisecond, - DATEPART(millisecond, @DateCre2Calcul), @DateCre2Calcul)
END
SET @NbJourneesNonTravaillees = 0
SET @NbNuits = DATEDIFF(day, @DateCreCalcul, @DateCre2Calcul)
-- Si les 2 dates sont à des jours différents, on cherche le nombre de jours NON travaillés entre les 2 dates
DECLARE @Compteur_NbNuits int;
SET @Compteur_NbNuits = 0;
-- Dans une boucle, on balaye tous les jours entre les 2 dates pour compter le nombre de jours non travaillés
WHILE @Compteur_NbNuits < @NbNuits
BEGIN
SET @Compteur_NbNuits = @Compteur_NbNuits + 1;
SET @LSTTEST = dbo.FN_JourTravailleFerie(DATEADD(day, @Compteur_NbNuits, @DateCreCalcul), 1)
IF @LSTTEST <> 'X'
BEGIN
SET @NbJourneesNonTravaillees = @NbJourneesNonTravaillees + 1
END
END
-- On calcule la différence en minutes et on retire :
-- - la durée des des nuits en minutes
-- - la durée des journées non travaillées en minutes
RETURN datediff(minute, @DateCreCalcul, @DateCre2Calcul) - 900*@NbNuits - 540*@NbJourneesNonTravaillees
END
23 sept. 2010 à 09:54
Ca dépend des ressources...
Pour moi le calcul est très rapide, sur plusieurs centaines, voire millier d'enregistrement.
22 sept. 2010 à 12:16
10 juin 2009 à 09:44