IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Procédural MySQL Discussion :

Calcul jours fériés


Sujet :

SQL Procédural MySQL

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2010
    Messages : 59
    Points : 55
    Points
    55
    Par défaut Calcul jours fériés
    Bonjour à tous.
    J'ai implémenter une procedure reposant sur l'algo de OUDIN afin définir les jours fériés pour l'année en cours.
    Pour 2012 et 2013 elle marche très bien MAIS pour l'année 2011, les jours fériés sont décalés d'UN jour.
    J'ai tourné le problème dans tous les sens, je n'arrive pas à voir d'où cela peut-il bien venir !

    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    DELIMITER |
    CREATE PROCEDURE JourFerie()
    BEGIN     
    DECLARE an INT;
    DECLARE G INT;
    DECLARE C INT;
    DECLARE C_4 INT;
    DECLARE E INT;
    DECLARE H INT;
    DECLARE K INT;
    DECLARE P INT;
    DECLARE Q INT;
    DECLARE I INT;
    DECLARE B INT;
    DECLARE J1 INT;
    DECLARE J2 INT;
    DECLARE R INT;
    DECLARE DimPaque DATETIME;     
    DECLARE LunPaque DATETIME;     
    DECLARE JeuAscension DATETIME;     
    DECLARE LunPentecote DATETIME;   
    DECLARE NouvelAn DATETIME;  
    DECLARE FeteTravail DATETIME;   
    DECLARE Armistice3945 DATETIME;   
    DECLARE Assomption DATETIME; 
    DECLARE Armistice1418 DATETIME;   
    DECLARE FeteNationale DATETIME;   
    DECLARE ToussaINT DATETIME; 
    DECLARE Noel DATETIME;  
     
    SET an = YEAR(CURDATE());    
    SET G = an % 19;
    SET C = an / 100;
    SET C_4 = C / 4;
    SET E = (8 * C + 13)/25;
    SET H = (19 * G + C - C_4 - E + 15) % 30;
    SET K = H / 28;
    SET P = 29 / (H + 1);
    SET Q = (21 - G)/11;
    SET I = (K * P * Q - 1) * K + H;
    SET B = (an / 4) + an;
    SET J1 = (B + I + 2 + C_4) - C;
    SET J2 = J1 % 7;
    SET R = 28 + I - J2;
    IF(R > 31) THEN
    SET DimPaque = CAST(CONCAT(CAST(an AS CHAR) , '-04-' , cast((R-31) AS CHAR)) AS DATETIME);
    ELSE
    SET DimPaque = CAST(CONCAT(CAST(an AS CHAR) , '-03-' , cast(R AS CHAR)) AS DATETIME);
    END IF;
     
    -- Jours fériés mobiles      
     
    SET LunPaque = ADDDATE(DimPaque,INTERVAL 1 DAY);
    SET JeuAscension = ADDDATE(DimPaque,INTERVAL 39 DAY);      
    SET LunPentecote = ADDDATE(DimPaque,INTERVAL 50 DAY);      
     
    -- Jours fériés fixes      
     
    SET NouvelAn = cast(CONCAT(cast(an AS CHAR),'-01-01 00:00:00') AS DATETIME);      
    SET FeteTravail = cast(CONCAT(cast(an AS CHAR),'-05-01 00:00:00') AS DATETIME);      
    SET Armistice3945 = cast(CONCAT(cast(an AS CHAR),'-05-08 00:00:00') AS DATETIME);      
    SET Assomption = cast(CONCAT(cast(an AS CHAR),'-08-15 00:00:00') AS DATETIME);      
    SET Armistice1418 = cast(CONCAT(cast(an AS CHAR),'-11-11 00:00:00') AS DATETIME);      
    SET FeteNationale = cast(CONCAT(cast(an AS CHAR),'-07-14 00:00:00') AS DATETIME);      
    SET ToussaINT = cast(CONCAT(cast(an AS CHAR),'-11-01 00:00:00') AS DATETIME);      
    SET Noel = cast(CONCAT(cast(an AS CHAR),'-12-25 00:00:00') AS DATETIME);      
     
    INSERT  INTO JoursFeries (JourDate, JoURLabel, JourChome)  
    SELECT  DimPaque, 'Dimanche de Pâques', 0    
    UNION 
    SELECT  LunPaque, 'Lundi de Pâques', 0  
    UNION 
    SELECT  JeuAscension, 'Jeudi de l''Ascension', 1    
    UNION   
    SELECT  LunPentecote, 'Lundi de Pentecôte', 1    
    UNION 
    SELECT  NouvelAn, 'Nouvel an', 1    
    UNION 
    SELECT  FeteTravail, 'Fête du travail', 1   
    UNION   
    SELECT  Armistice3945, 'Armistice 39-45', 1   
    UNION  
    SELECT  Assomption, 'Assomption', 1   
    UNION 
    SELECT  FeteNationale, 'Fête Nationale', 1   
    UNION 
    SELECT  ToussaINT, 'Toussaint', 1   
    UNION 
    SELECT  Armistice1418, 'Armistice 14-18', 1    
    UNION 
    SELECT  Noel, 'Noël', 0;  
     
    END|
    DELIMITER ;
    Si quelqu'un trouve une solution, je suis preneur...

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Peut-être trouverez-vous une piste dans l'article de SQLPro sur le sujet de la gestion du temps.

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2010
    Messages : 59
    Points : 55
    Points
    55
    Par défaut
    Tout d'abord, merci de votre réponse.
    J'ai consulté le lien que vous m'avez donné, mais malheureusement je n'ai pas trouvé de réponse à ma question.
    Ça doit vraiment se jouer à un cheveu, car la fonction marche très bien pour l'année 2012 et 2013.
    Pour 2011 et 2014, le Dimanche de Pâques est calculé un jour trop tôt...

  4. #4
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2010
    Messages : 59
    Points : 55
    Points
    55
    Par défaut
    Aucune solution ?
    C'est dommage, je suis sûr que cette procédure mySQL pourrait servir à beaucoup de monde.

  5. #5
    Membre régulier
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2006
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Transports

    Informations forums :
    Inscription : Février 2006
    Messages : 102
    Points : 119
    Points
    119
    Par défaut
    Bonjour,

    Je suis tombé sur cette procédure en PGPLSQL qui devrait vous permettre de corriger l'erreur :

    blog.guillaume.lelarge.info/index.php/post/2006/02/07/431-vacances-en-pl-pgsql

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2010
    Messages : 59
    Points : 55
    Points
    55
    Par défaut
    Bonjour,

    malheureusement j'ai sensiblement fait la même démarche que sur le lien que vous m'avez envoyé.

    L'algo de Oudin est appliqué texto dans mon script, donc je ne comprend pas comment pour les années 2011 et 2014, le résultat est décalé d'UN jour.

    (Ce n'est même pas une histoire d'année bissextile, car 2012 et 2013 marchent très bien, sachant qu'un des deux est bissextile.)

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 904
    Points : 51 652
    Points
    51 652
    Billets dans le blog
    6
    Par défaut
    C'est sans doute à cause de l'imprécision de vos calculs.
    En effet suivant le type SQL de données que vous utilisez, quelques minutes par ci, par là en plus ou en moins peuvent faire basculer la date d'une journée.

    Pour ma part, sous MS SQL Server, je me sers des procédures que j'ai écrites et qui me donnent des résultats exacts.
    Mais MySQL est bien loin d'égaler MS SQL Server, d'autant qu'il utilise des types de données spécifiques qui n'existent nullement dans la norme SQL...

    A +

  8. #8
    Membre régulier
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2006
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Transports

    Informations forums :
    Inscription : Février 2006
    Messages : 102
    Points : 119
    Points
    119
    Par défaut
    Même avis que SQLPro, ayant testé sous mysql et postgresql (pas eu le temps sur SQL Server) il y a bien un écart... Celui-ci se retrouve dans plusieurs fonctions de calculs qui me pousse aujourd'hui à migrer mes bases vers postgresql (marre de vérifier l’invérifiable !)

  9. #9
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2010
    Messages : 59
    Points : 55
    Points
    55
    Par défaut
    Je me doutais que c'était une question de calcul, mais merci à vous pour la confirmation.

    Cependant mon patron voulant absolument mySQL, je me retrouve un peu roulé.

    Tant pis, ce sera une table de jours fériés en dur pour les 15 prochaines années alors.

  10. #10
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 904
    Points : 51 652
    Points
    51 652
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par Logarithmix Voir le message
    Cependant mon patron voulant absolument mySQL, je me retrouve un peu roulé.
    C'est dommage d'utiliser un produit commercial, payant et franchement pas terrible (c'est même pas un vrai SGBDR - à lire : http://blog.developpez.com/sqlpro/p9...udre-aux-yeux/) alors qu'il en existe d'excellent et réellement gratuit, car pas commercial...comme PostGreSQL !

    A +

  11. #11
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    salut,

    un truc qui peut te sauver est de t'assurer de travailler sur du float (en mettant les littéraux comme 19 à 19.0 par exemple) et de forcer la conversion float vers entier en jouant avec les fonctions d'arrondi dans ta procédure stocker...

    si ça peut t'éviter de générer tes 15 prochaines années à la main

  12. #12
    Candidat au Club
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Avril 2023
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2023
    Messages : 1
    Points : 3
    Points
    3
    Par défaut Pour la postérité
    Bonjour à tous,

    Voici la version MySQL pour créer la fonction F_CALCULE_PAQUES adaptée bien entendu du code SQL Server de SQLPro


    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
     
    DELIMITER $$
    CREATE FUNCTION F_CALCULE_PAQUES (AN INT) RETURNS DATE
    BEGIN
       DECLARE G,C,B,C4,E,H,K,P,Q,I,J1,J2,R INT;
       SET G = MOD(AN, 19);
       SET C = FLOOR(AN / 100);
       SET B = FLOOR(AN / 4) + AN;
       SET C4 = FLOOR(C / 4);
       SET E = FLOOR(((8 * C) + 13) / 25);
       SET H = MOD(((19 * G) + C - C4 - E + 15) , 30);
       SET K = FLOOR(H / 28);
       SET P = FLOOR(29 / (H + 1));
       SET Q = FLOOR((21 - G) / 11);
       SET I = (((K * P * Q) - 1 ) * K) + H;
       SET J1 = B + I + 2 + C4 - C;
       SET J2 = MOD(J1,7);
       SET R = 28 + I - J2;
       RETURN DATE_ADD(DATE_ADD(MAKEDATE(AN, 1), INTERVAL 2 MONTH), INTERVAL R - 1 day);
    END;
    $$
     
    DELIMITER ;

  13. #13
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 904
    Points : 51 652
    Points
    51 652
    Billets dans le blog
    6
    Par défaut
    Bref il a fallut 12 ans pour que MySQL puisse enfin calculer quelque chose de simple sans erreur par rapport à tous les autres SGBDR ! ça promet !

    A +

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 09/09/2010, 17h47
  2. fonction calcul jours fériés
    Par Daniel MOREAU dans le forum Développement
    Réponses: 1
    Dernier message: 25/11/2009, 09h48
  3. [XL-2003] calcul de moyenne avec des jours fériés
    Par arnest dans le forum Excel
    Réponses: 3
    Dernier message: 22/11/2009, 18h06
  4. Calcule jours fériés entre 2 dates
    Par Ouggada dans le forum Windows Forms
    Réponses: 3
    Dernier message: 05/03/2009, 13h30
  5. [MySQL] calcul sans jours fériées
    Par tigre198 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 20/05/2008, 09h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo