begin process at 2010 07 29 22:23:56
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Fonctions

 > CALCUL UNE DIFFÉRENCE DE DATE EN FONCTION DE JOURS FÉRIÉS/TRAVAILLÉS ET DE PLAGE HORAIRE

CALCUL UNE DIFFÉRENCE DE DATE EN FONCTION DE JOURS FÉRIÉS/TRAVAILLÉS ET DE PLAGE HORAIRE


 Information sur la source

Note :
Aucune note
Catégorie :Fonctions Classé sous :datediff, datetime, différence, heure, minutes Niveau :Initié Date de création :15/05/2009 Vu / téléchargé :8 567 / 319

Auteur : Sieurcoug

Ecrire un message privé
Commentaire sur cette source (1)
Ajouter un commentaire et/ou une note

 Description

Cette fonction permet de calculer une différence en minutes entre deux dates/heures, dans le cadre (le plus souvent) d'une entreprise.
La fonction donne la différence et déduit :
- les nuits en dehors de la plage horaire
- les samedis et dimanches
- les jours fériés

Pour l'utiliser :
dbo.FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE(Date1, Date2)  => Fait la différence Date2 - Date1 avec le traitement cité ci-dessus

Exemple :
SELECT dbo.FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE('14/05/2 009 12:00:00', '14/05/2009 13:05:00') AS 'Différence (en minutes)'
Ou :
PRINT dbo.FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE ('07/05/2009 17:30:00', '11/05/2009 08:05:00')

Pour le calcul dynamique des jours fériés, je me suis basé sur ce script :
http://www.sqlfr.com/codes/ORACLE-SQL-SERVER-2K- FONCTION-RETOURNANT-STATUS-OUVRE_27798.aspx

Source

  • --====================================================================--
  • -- Ensemble de fonctions de calculs de date avec jours fériés
  • --====================================================================--
  • -----------------------------------------------------------------------
  • -- FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE
  • -- calcule la différence en minutes entre deux dates
  • -- en fonction des horaires de l'ENTREPRISE :
  • -- ici : 08h00 - 18h00
  • --
  • -- Déduit les nuits entre 18h00 et 08h00 le lendemain
  • -- ainsi que les week-ends et les jours fériés
  • -----------------------------------------------------------------------
  • GO
  • IF EXISTS (SELECT name FROM sysobjects WHERE name = 'FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE')
  • DROP FUNCTION dbo.FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE
  • GO
  • CREATE FUNCTION FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE (@Date1 DATETIME, @Date2 DATETIME)
  • RETURNS INT AS
  • BEGIN
  • DECLARE @DateCreCalcul DATETIME
  • DECLARE @NbJourneesNonTravaillees INT
  • DECLARE @NbNuits INT
  • SET @DateCreCalcul = @Date1
  • -- Si Date1 inférieure à l'heure d'ouverture
  • IF DATEPART(hour, @Date1) < 8
  • BEGIN
  • SET @DateCreCalcul = DATEADD(hour, - DATEPART(hour, @Date1) + 8, @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 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 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) + 8, @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 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) + 8, @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
  • SET @NbJourneesNonTravaillees = 0
  • SET @NbNuits = DATEDIFF(day, @DateCreCalcul, @Date2)
  • -- 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;
  • IF dbo.FN_JourTravailleFerie(DATEADD(day, @NbJourneesNonTravaillees + 1, @DateCreCalcul), 1) <> '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, @Date2) - 840*@NbNuits - 600*@NbJourneesNonTravaillees
  • END
  • GO
  • -----------------------------------------------------------------------
  • -- Ensembles de fonctions qui déterminent si un jour est travaillé,
  • -- week-end ou férié
  • --
  • -- Entrée : date à tester,
  • -- Considérer le samedi comme un jour férié ?
  • -- Par défaut les samedi sont considérés comme fériés
  • -- 0 : est considéré travaillé
  • -- 1 : est considéré férié
  • --
  • -- Sortie : chaine de caractère
  • -- X : jour travaillé
  • -- WE : Week-end
  • -- JF : Jour férié
  • --
  • -- Exemples d'appel de la fonction :
  • -- dbo.FN_JourTravailleFerie(getdate(), 1)
  • -- dbo.FN_JourTravailleFerie('21/04/2009', 1)
  • -----------------------------------------------------------------------
  • -----------------------------------------------------------------------
  • -- ================================================================= --
  • -----------------------------------------------------------------------
  • GO
  • IF EXISTS(SELECT * FROM sysobjects WHERE name = 'Mini' AND type = 'FN') DROP FUNCTION Mini
  • GO
  • CREATE FUNCTION Mini(@a float, @b float) returns float
  • AS
  • BEGIN
  • DECLARE @f float
  • if @a < @b
  • SET @f = @a
  • ELSE
  • SET @f = @b
  • return @f
  • END
  • GO
  • -----------------------------------------------------------------------
  • -- ================================================================= --
  • -----------------------------------------------------------------------
  • IF EXISTS(SELECT * FROM sysobjects WHERE name = 'Maxi' AND type = 'FN') DROP FUNCTION Maxi
  • GO
  • CREATE FUNCTION Maxi(@a float, @b float) returns float
  • AS
  • BEGIN
  • DECLARE @f float
  • IF @a > @b
  • SET @f = @a
  • ELSE
  • SET @f = @b
  • return @f
  • END
  • GO
  • -----------------------------------------------------------------------
  • -- ================================================================= --
  • -----------------------------------------------------------------------
  • IF EXISTS(SELECT * FROM sysobjects WHERE name = 'IsCorrectDate' AND type = 'FN') DROP FUNCTION IsCorrectDate
  • GO
  • CREATE FUNCTION IsCorrectDate (@JJ integer, @MM integer, @AAAA integer) returns integer
  • AS
  • BEGIN
  • DECLARE @FlagReturn integer
  • -- Hors plage
  • IF @JJ < 1 Or @JJ > 31 Or @MM < 1 Or @MM > 12
  • BEGIN
  • SET @FlagReturn = 0
  • END
  • ELSE
  • BEGIN
  • -- Mois de 30 jours
  • IF @JJ = 31 AND (@MM = 4 Or @MM = 6 Or @MM = 9 Or @MM = 11)
  • BEGIN
  • SET @FlagReturn = 0
  • END
  • ELSE
  • BEGIN
  • -- Mois de février
  • IF @MM = 2
  • BEGIN
  • IF @JJ <= 28
  • BEGIN
  • SET @FlagReturn = 1
  • END
  • ELSE
  • BEGIN
  • IF @JJ > 29
  • BEGIN
  • SET @FlagReturn = 0
  • END
  • ELSE
  • BEGIN
  • IF Not (@JJ = 29 AND ((@AAAA % 4 = 0 AND @AAAA % 100 <> 0) Or @AAAA % 400 = 0))
  • BEGIN
  • SET @FlagReturn = 0
  • END
  • ELSE
  • BEGIN
  • SET @FlagReturn = 1
  • END
  • END
  • END
  • END
  • ELSE -- mois autre que fevrier
  • BEGIN
  • SET @FlagReturn = 1
  • END
  • END
  • END
  • Return @FlagReturn
  • END
  • GO
  • -----------------------------------------------------------------------
  • -- ================================================================= --
  • -----------------------------------------------------------------------
  • IF EXISTS(SELECT * FROM sysobjects WHERE name = 'ConvertDate' AND type = 'FN') DROP FUNCTION ConvertDate
  • GO
  • CREATE FUNCTION ConvertDate (@dtDate DateTime) returns varchar(4)
  • AS
  • BEGIN
  • DECLARE
  • @iJour integer,
  • @iMois integer,
  • @sJour varchar(2),
  • @sMois varchar(2),
  • @sResult varchar(4)
  • SET @iJour = datepart(dd, @dtDate)
  • SET @iMois = datepart(mm, @dtDate)
  • SET @sJour = CAST(@iJour AS VARCHAR)
  • SET @sMois = CAST(@iMois AS VARCHAR)
  • IF len(@sJour) = 1
  • BEGIN
  • SET @sJour = '0' + @sJour
  • END
  • IF len(@sMois) = 1
  • BEGIN
  • SET @sMois = '0' + @sMois
  • END
  • SET @sResult = @sJour + @sMois
  • RETURN @sResult
  • END
  • GO
  • -----------------------------------------------------------------------
  • -- ================================================================= --
  • -----------------------------------------------------------------------
  • IF EXISTS(SELECT * FROM sysobjects WHERE name = 'FN_JourTravailleFerie' AND type = 'FN') DROP FUNCTION FN_JourTravailleFerie
  • GO
  • CREATE FUNCTION FN_JourTravailleFerie (@dtDate DateTime, @iSamediFerie integer = 1) returns varchar(2)
  • AS
  • BEGIN
  • -- Cette fonction indique si le jour passé en argument est férié.
  • -- Par défaut les samedi sont considérés comme fériés, mais le second
  • -- paramètre permet de changer cela.
  • DECLARE
  • @lgA bigint,
  • @lgMPaq bigint,
  • @lgJPaq bigint,
  • @lgTmp1 bigint,
  • @lgTmp2 bigint,
  • @lgTmp3 bigint,
  • @stDate varchar(10),
  • @dtPaq DateTime,
  • @stPaq varchar(10),
  • @blFerie integer,
  • @stType varchar(2)
  • SET @stType = 'X'
  • -- Dimanche (et samedi)
  • IF @iSamediFerie = 1
  • BEGIN
  • IF DatePart(weekday, @dtDate) = 7 OR DatePart(weekday, @dtDate) = 6
  • BEGIN
  • SET @blFerie = 1
  • END
  • ELSE
  • BEGIN
  • SET @blFerie = 0
  • END
  • END
  • ELSE
  • BEGIN
  • IF DatePart(weekday, @dtDate) = 7
  • BEGIN
  • SET @blFerie = 1
  • END
  • ELSE
  • BEGIN
  • SET @blFerie =0
  • END
  • END
  • IF @blFerie = 1
  • BEGIN
  • SET @stType = 'WE'
  • END
  • IF @blFerie = 0
  • BEGIN
  • SET @stDate = dbo.ConvertDate(@dtDate)
  • -- Jours fériés fixes (1er janvier, 1er mai, 8 mai, 14 juillet, ...)
  • IF @stDate IN ('0101','0105','0805','1407','1508','0111','1111','2512')
  • BEGIN
  • SET @blFerie = 1
  • END
  • END
  • IF @blFerie = 0
  • BEGIN
  • SET @lgA = Year(@dtDate)
  • SET @lgTmp1 = (19 * (@lgA % 19) + 24) % 30
  • SET @lgTmp2 = dbo.Mini(@lgTmp1, dbo.Maxi(28, @lgTmp1) - 1)
  • SET @lgTmp3 = 28 + @lgTmp2 - ((3 + @lgA - 1900 + ((@lgA - 1900) / 4) + @lgTmp2) % 7)
  • SET @lgMPaq = 3 + (@lgTmp3 / 32)
  • -- Remarque Le calcul du jour de pâques ne fonctionne pas toujours. L'arrondi est mauvais lorsqu'il y a une division : mettre un TRUNC(ladivision,0) pour garder la partie entière.
  • -- http://www.sqlfr.com/codes/ORACLE-SQL-SERVER-2K-FONCTION-RETOURNANT-STATUS-OUVRE_27798.aspx
  • -- SET @lgMPaq = 3 + round((@lgTmp3 / 32), 0)
  • IF (@lgTmp3 < 32)
  • BEGIN
  • SET @lgJPaq = @lgTmp3
  • END
  • ELSE
  • BEGIN
  • SET @lgJPaq = @lgTmp3 - 31
  • END
  • -- Construction de la date du dimanche de Pâques
  • SET @stPaq = CAST(@lgJPaq AS varchar) + '/' + CAST(@lgMPaq AS varchar) + '/' + CAST(@lgA AS varchar)
  • SET @dtPaq = CAST (@stPaq AS DateTime)
  • -- Jours fériés mobiles (lundi de pâques, ascension, lundi de pentecôte)
  • -- Pâques et Pentecôte non testés, puisqu'ils tombent tous les deux un dimanche.
  • IF (@dtDate = (@dtPaq + 1)) Or (@dtDate = (@dtPaq + 39)) Or (@dtDate = (@dtPaq + 50))
  • BEGIN
  • SET @blFerie = 1
  • END
  • END
  • IF @blFerie = 1 AND @stType = 'X'
  • BEGIN
  • SET @stType = 'JF'
  • END
  • RETURN @stType
  • END
  • GO
--====================================================================--
--    Ensemble de fonctions de calculs de date avec jours fériés
--====================================================================--



-----------------------------------------------------------------------
-- FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE
-- calcule la différence en minutes entre deux dates
-- en fonction des horaires de l'ENTREPRISE : 
-- ici : 08h00 - 18h00
--
-- Déduit les nuits entre 18h00 et 08h00 le lendemain
-- ainsi que les week-ends et les jours fériés
-----------------------------------------------------------------------
GO
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE')
	DROP FUNCTION dbo.FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE
GO
CREATE FUNCTION FN_DATEDIFF_SELON_HORAIRES_ENTREPRISE (@Date1 DATETIME, @Date2 DATETIME)
	RETURNS INT AS
	BEGIN
		DECLARE @DateCreCalcul DATETIME
		DECLARE @NbJourneesNonTravaillees INT
		DECLARE @NbNuits INT

		SET @DateCreCalcul = @Date1
		-- Si Date1 inférieure à l'heure d'ouverture
		IF DATEPART(hour, @Date1) < 8
		BEGIN
			SET @DateCreCalcul = DATEADD(hour, - DATEPART(hour, @Date1) + 8, @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 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 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) + 8, @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 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) + 8, @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

		SET @NbJourneesNonTravaillees = 0	
		SET @NbNuits = DATEDIFF(day, @DateCreCalcul, @Date2)
		-- 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;
				IF dbo.FN_JourTravailleFerie(DATEADD(day, @NbJourneesNonTravaillees + 1, @DateCreCalcul), 1) <> '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, @Date2) - 840*@NbNuits - 600*@NbJourneesNonTravaillees
END
GO


-----------------------------------------------------------------------
-- Ensembles de fonctions qui déterminent si un jour est travaillé,
-- week-end ou férié
--
-- Entrée : date à tester,
--			Considérer le samedi comme un jour férié ?
--				Par défaut les samedi sont considérés comme fériés
--				0 : est considéré travaillé
--				1 : est considéré férié
--
-- Sortie :	chaine de caractère
--				X :	 jour travaillé
--				WE : Week-end
--				JF : Jour férié
--
-- Exemples d'appel de la fonction :
--			dbo.FN_JourTravailleFerie(getdate(), 1)
--			dbo.FN_JourTravailleFerie('21/04/2009', 1)
-----------------------------------------------------------------------


-----------------------------------------------------------------------
-- ================================================================= --
-----------------------------------------------------------------------
GO
IF EXISTS(SELECT * FROM sysobjects WHERE name = 'Mini' AND type = 'FN') DROP FUNCTION Mini
GO
CREATE FUNCTION Mini(@a float, @b float) returns float
AS
BEGIN
	DECLARE @f float
	if @a < @b 
		SET @f = @a
	ELSE
		SET @f = @b
	return @f
END
GO

-----------------------------------------------------------------------
-- ================================================================= --
-----------------------------------------------------------------------
IF EXISTS(SELECT * FROM sysobjects WHERE name = 'Maxi' AND type = 'FN') DROP FUNCTION Maxi
GO
CREATE FUNCTION Maxi(@a float, @b float) returns float
AS
BEGIN
	DECLARE @f float
	IF @a > @b 
		SET @f = @a
	ELSE
		SET @f = @b
	return @f
END
GO

-----------------------------------------------------------------------
-- ================================================================= --
-----------------------------------------------------------------------
IF EXISTS(SELECT * FROM sysobjects WHERE name = 'IsCorrectDate' AND type = 'FN') DROP FUNCTION IsCorrectDate
GO
CREATE FUNCTION IsCorrectDate (@JJ integer, @MM integer, @AAAA integer) returns integer 
AS
BEGIN
	DECLARE @FlagReturn integer
    -- Hors plage
    IF @JJ < 1 Or @JJ > 31 Or @MM < 1 Or @MM > 12 
	  BEGIN
        SET @FlagReturn = 0
      END
    ELSE
    BEGIN
    -- Mois de 30 jours
    IF @JJ = 31 AND (@MM = 4 Or @MM = 6 Or @MM = 9 Or @MM = 11) 
      BEGIN
        SET @FlagReturn = 0
      END
    ELSE
    BEGIN
    -- Mois de février
     IF @MM = 2 
       BEGIN
         IF @JJ <= 28 
           BEGIN
             SET @FlagReturn = 1
           END
         ELSE
           BEGIN
             IF @JJ > 29 
               BEGIN
                 SET @FlagReturn = 0
               END
             ELSE  
               BEGIN
             	 IF Not (@JJ = 29 AND ((@AAAA % 4 = 0 AND @AAAA % 100 <> 0) Or @AAAA % 400 = 0))
             	   BEGIN
                     SET @FlagReturn = 0
                   END
                 ELSE
                   BEGIN
                     SET @FlagReturn = 1
                   END
               END
           END          
       END
       ELSE -- mois autre que fevrier
         BEGIN
         	SET @FlagReturn = 1
         END	
    END
    END
    Return @FlagReturn
END
GO

-----------------------------------------------------------------------
-- ================================================================= --
-----------------------------------------------------------------------
IF EXISTS(SELECT * FROM sysobjects WHERE name = 'ConvertDate' AND type = 'FN') DROP FUNCTION ConvertDate
GO
CREATE FUNCTION ConvertDate (@dtDate DateTime) returns varchar(4) 
AS
BEGIN
  DECLARE
  	@iJour integer,
  	@iMois integer,
  	@sJour varchar(2),
  	@sMois varchar(2),
  	@sResult varchar(4)

  SET @iJour = datepart(dd, @dtDate)
  SET @iMois = datepart(mm, @dtDate)

  SET @sJour = CAST(@iJour AS VARCHAR)
  SET @sMois = CAST(@iMois AS VARCHAR)

  IF len(@sJour) = 1 
    BEGIN
      SET @sJour = '0' + @sJour
    END
    
  IF len(@sMois) = 1 
    BEGIN
      SET @sMois = '0' + @sMois
    END
  
  SET @sResult = @sJour + @sMois

  RETURN @sResult
END
GO


-----------------------------------------------------------------------
-- ================================================================= --
-----------------------------------------------------------------------
IF EXISTS(SELECT * FROM sysobjects WHERE name = 'FN_JourTravailleFerie' AND type = 'FN') DROP FUNCTION FN_JourTravailleFerie
GO
CREATE FUNCTION FN_JourTravailleFerie (@dtDate DateTime, @iSamediFerie integer = 1) returns varchar(2)
AS
BEGIN

-- Cette fonction indique si le jour passé en argument est férié.
-- Par défaut les samedi sont considérés comme fériés, mais le second
-- paramètre permet de changer cela.

DECLARE 
	@lgA bigint,
	@lgMPaq bigint,
	@lgJPaq bigint,
	@lgTmp1 bigint, 
	@lgTmp2 bigint, 
	@lgTmp3 bigint,
	@stDate varchar(10),
	@dtPaq DateTime,
	@stPaq varchar(10),
	@blFerie integer,
	@stType varchar(2)

 
SET @stType = 'X'
-- Dimanche (et samedi)

IF @iSamediFerie = 1 
  BEGIN
    IF DatePart(weekday, @dtDate) = 7 OR DatePart(weekday, @dtDate) = 6 
      BEGIN
        SET @blFerie = 1
      END
    ELSE
      BEGIN
        SET @blFerie = 0
      END
  END  
ELSE
  BEGIN
    IF DatePart(weekday, @dtDate) = 7 
      BEGIN
        SET @blFerie = 1
      END
    ELSE
      BEGIN
        SET @blFerie =0
      END
  END




IF @blFerie = 1 
  BEGIN
    SET @stType = 'WE'
  END
  
IF @blFerie = 0 
  BEGIN
    SET @stDate = dbo.ConvertDate(@dtDate)
    -- Jours fériés fixes (1er janvier, 1er mai, 8 mai, 14 juillet, ...)
    IF @stDate IN ('0101','0105','0805','1407','1508','0111','1111','2512')
      BEGIN
        SET @blFerie = 1
      END
  END
 
IF @blFerie = 0
  BEGIN
    SET @lgA = Year(@dtDate)
    SET @lgTmp1 = (19 * (@lgA % 19) + 24) % 30
    SET @lgTmp2 = dbo.Mini(@lgTmp1, dbo.Maxi(28, @lgTmp1) - 1)
    SET @lgTmp3 = 28 + @lgTmp2 - ((3 + @lgA - 1900 + ((@lgA - 1900) / 4) + @lgTmp2) % 7)
    SET @lgMPaq = 3 + (@lgTmp3 / 32)
	-- Remarque Le calcul du jour de pâques ne fonctionne pas toujours. L'arrondi est mauvais lorsqu'il y a une division : mettre un TRUNC(ladivision,0) pour garder la partie entière.
	-- http://www.sqlfr.com/codes/ORACLE-SQL-SERVER-2K-FONCTION-RETOURNANT-STATUS-OUVRE_27798.aspx
	-- SET @lgMPaq = 3 + round((@lgTmp3 / 32), 0)
    
    IF (@lgTmp3 < 32) 
    	BEGIN
    	  SET @lgJPaq = @lgTmp3 
    	END
    ELSE 
    	BEGIN
    	  SET @lgJPaq = @lgTmp3 - 31
    	END
    	
    -- Construction de la date du dimanche de Pâques
    SET @stPaq = CAST(@lgJPaq AS varchar) + '/' + CAST(@lgMPaq AS varchar) + '/' + CAST(@lgA AS varchar)
    SET @dtPaq = CAST (@stPaq AS DateTime)
    -- Jours fériés mobiles (lundi de pâques, ascension, lundi de pentecôte)
    -- Pâques et Pentecôte non testés, puisqu'ils tombent tous les deux un dimanche.
    
    IF (@dtDate = (@dtPaq + 1)) Or (@dtDate = (@dtPaq + 39)) Or (@dtDate = (@dtPaq + 50))
      BEGIN
        SET @blFerie = 1
      END
    
  END
 
IF @blFerie = 1 AND @stType = 'X'
  BEGIN
    SET @stType = 'JF'
  END 
 
 RETURN @stType  
 
END 
GO

 Conclusion

L'heure pour Date1 est retravaillée pour coller à la plage horaire :
- si elle est inférieure à l'heure d'ouverture, on prend en compte l'heure d'ouverture
- si elle est supérieure à l'heure de fermeture, on prend en compte l'heure de fermeture
L'heure pour Date2 n'est retravaillée.


Remarque : j'ai développé cette fonction pour mon cas précis. Elle devra probablement être adaptée pour d'autres cas (horaires d'ouverture/fermeture par exemple) mais cela donne un départ, c'est pour ça que je la partage.
Vos commentaires sont les bienvenus.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources de la même categorie

Source avec Zip CONVERSION DE NOMBRE EN LETTRES (SQL) par wormlore
NO HTML BALISE [MYSQL] par abdoulax
MYSQL : FONCTION POUR GÉRER DES COMPTEURS ÉQUIVALENT AUX SÉQ... par maitredede
RÉINDEXER TOUTES LES TABLES D'UNE BASE DE DONNÉES par pneau
Source avec une capture SQL SERVER - TRANSMISSION D'UN PARAMETRE A VALEURS MULTIPLES par FENETRES

 Sources en rapport avec celle ci

FAIRE UN COUNT ET GROUPER PAR DATE AVEC LA MÉTHODE FLOOR par Nix
[SQL SERVER] AJOUTER X MINUTES À UNE HEURE DONNÉE ÉCRITE DE ... par Benouille
FONCTIONS DATEADD, DATEDIFF, DATENAME ET DATEPART par frop01

Commentaires et avis

Commentaire de dymsbess le 10/06/2009 09:44:45

Voici une fontion complétaire permettant de ressortir la liste des jours fériés pour l'année en cours : http://www.xoowiki.com/Article/SQL-Server/liste-des-jours-feries-47.aspx

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Calcul de la différence de temps entre deux tuples [ par lofo18 ] Bonjour tout le monde!Dans le cadre d'un projet pour le domaine médical, Je dois calculer le temps moyen entre deux interventions, mais je bloque comp [SQL Server] Modifier/forcer l'heure d'un DATETIME [ par Sieurcoug ] Bonjour,Dans une fonction, j'ai besoin de forcer l'heure d'un DATETIME.Par exemple si l'heure de création est inférieure à 8h00, il faut retenir 8h00 sql server datetime [ par brmdevinci ] svp j'execute cette requete " select * from personne where date_nais='12/02/1986'" la resultat est un tableau vide sachant que quand j'ai remplit la Format Date et Heure [ par NICK123 ] Bonjour, mon problème est comment afficher une zone datetime comme date (DD/MM/YYYY) ou heure (HH:MM:SS) et pas DD/MM/YYYY HH:MM:SS Merci calcul de durée sous Access [ par lili20 ] Bonjour, Dans mon formulaire frmDateTabulaire je voudrais calculer les valeurs des 3 champs suivants: -Durée de 8h et 16h -Durée de 16h et 24h -Dur Afficher un résultat en fonction de la péiode horaire depuis un Datetime [ par cesidoo ] [size=100]Bonjour à tous, Je suis bien ennuyé autour des questions de datetime (comme beaucoup.. je sais. J&#8217;ai une colonne Datetime et je cherc Comparer date('y-m-d') avec un champs DATETIME [ par reedbedroom ] Bonjour à tous, Je recherche à pouvoir comparer une date simple obtenu par date('y-m-d')avec un champs datetime situé dans une table. Mon souci est Format régionnal datetime [ par fabienfs ] Bonjour, Je viens d'installer SQL Server 2005 Standard édition sur mon seveur Windows 2003. Les paramètres régionnaux de Windows sont bien en françai WD14 requête ODBC champ "Heure" vide [ par NaoBromont ] Bonjour, Je crée une requête par lien ODBC sur une base de données WD14 et les champs de type "Heure" me retournent des valeurs vides. Je fais cette m sqlserver datetime [ par koukou09 ] Salut, je veux faire une insertion des données dans sqlserver à partir d'un frame dans parmi les composant une date qui est définit comme type date


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Juillet 2010
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,827 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales