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

Langage SQL Discussion :

Date anniversaire et années bissextiles


Sujet :

Langage SQL

  1. #1
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2003
    Messages : 422
    Points : 243
    Points
    243
    Par défaut Date anniversaire et années bissextiles
    Hello,

    Un petit problème bête: sur un site j'affiche si un utilisateur a son anniversaire, s'il l'a demain ou l'a eu hier.

    Ma méthode actuelle :

    Je fais ce test dans la requête SQL en utilisant la fonction DAYOFYEAR :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DAYOFYEAR(J.DOBJOUEUR) - DAYOFYEAR(CURDATE()) AS QUAND
    Ceci me retourne une valeur en sachant que je ne garde que les valeurs entre -1 et 1 signifiant si l'anniversaire a eu lieu la veille, a lieu aujourd'hui ou aura lieu demain.


    Le problème : ça ne fonctionne plus correctement si un utilisateur est né lors d'une année bissextile ou si on se trouve dans une année bissextile.

    Avez-vous des idées pour faire ce test en PHP ?

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    il l'a eu n'y hier ni demain puisque le jour n'existe pas, t’embêtes pas pour ce genre de chose

  3. #3
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2003
    Messages : 422
    Points : 243
    Points
    243
    Par défaut
    Si un utilisateur est né le 10 juin, ce jour existe que l'année soit bissextile ou non. Par contre le calcul DAYOFYEAR ne retourne pas la même valeur, ce qui cause mon problème.

    Pour le cas extrême où un utilisateur serait né le 29 février, je peux gérer par un If.

  4. #4
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    fait ton if alors ou est le problème ?

  5. #5
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2003
    Messages : 422
    Points : 243
    Points
    243
    Par défaut
    Citation Envoyé par stealth35 Voir le message
    fait ton if alors ou est le problème ?
    Le but est d'avoir une fonction qui retourne de -1 à 1 pour savoir si un jour se situe avant ou après le jour courant de manière simple. ça éviterait de devoir tout tester "1. L'utilisateur est-il né une année bissextile, 2. Sommes-nous dans une année bissextile, 3. L'utilisateur est-il né un 29 février" et de gérer tous ces cas y compris lorsqu'ils s'imbriquent.
    N'y a-t-il pas de fonction PHP de comparaison de date permettant de gérer ces cas ?

  6. #6
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    il va bien falloir lui définir une date par contre, si on est pas dans un année bissextile son anniversaire c'est le 28 ou 1 ? sinon tu verras que ça colle pas

  7. #7
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2003
    Messages
    422
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2003
    Messages : 422
    Points : 243
    Points
    243
    Par défaut
    La date c'est la date de naissance de l'utilisateur, je reprends mon exemple du 10 juin. Ma fonction actuelle dans la requête SQL DAYOFYEAR() ne retourne pas la même valeur si l'utilisateur est né le 10 juin 1996 (bissextile) ou 10 juin 1997.

    Effectivement comme tu le dis le problème se pose uniquement si l'utilisateur est né une année bissextile après le 29 février, ce qui complique encore l'affaire.

    Bref, je cherche un moyen d'afficher "John Doe a son anniversaire hier / aujourd'hui / demain" en gérant tous ces cas. Je pensais qu'il existait des moyens simples en PHP, mais si ce n'est pas le cas je gérerai dans une fonction plus complexe.

  8. #8
    Expert éminent sénior
    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
    Facile à faire en SQL avec les fonctions de dates propre à ton SGBD et un CASE WHEN.
    Avec MySQL, ça donnerait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT 
        CASE
            WHEN DATEDIFF(DOBJOUEUR, CURRENT_DATE) = 1 THEN 'demain'
            WHEN DATEDIFF(DOBJOUEUR, CURRENT_DATE) = (-1) THEN 'hier'
            ELSE 'un autre jour'
        END AS Quand

  9. #9
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 115
    Points : 28 480
    Points
    28 480
    Par défaut
    Nous sommes ici sur le forum Langage SQL, je n'utiliserai donc que les fonctions normalisées pour résoudre ton problème.

    L'expression la plus simple pour calculer une date d'anniversaire est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dobjoueur + INTERVAL (EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM dobjoueur)) YEAR
    Donc pour calculer ton hier-aujourd’hui-demain, il suffirait de se baser sur le résultat de CURRENT_DATE - (dobjoueur + INTERVAL (EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM dobjoueur)) YEAR).

    Malheureusement, lorsqu'on arrive sur le début/fin d'année, le résultat n'est plus cohérent.

    Je suis donc arrivé à la requête suivante :
    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
    SELECT  anniv + INTERVAL (CASE WHEN reste1 <= 1 THEN 0 WHEN reste2 <= 1 THEN -1 WHEN reste3 <= 1 THEN 1 END) YEAR   AS anniversaire
        ,   CASE CURRENT_DATE - (anniv + INTERVAL (CASE WHEN reste1 <= 1 THEN 0 WHEN reste2 <= 1 THEN -1 WHEN reste3 <= 1 THEN 1 END) YEAR)
                WHEN +1 THEN 'hier'
                WHEN  0 THEN 'aujourd''hui'
                WHEN -1 THEN 'demain'
            END AS quand
    FROM    (   SELECT  dobjoueur + INTERVAL (EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM dobjoueur)) YEAR  AS anniv
                    ,   ABS(CURRENT_DATE - (dobjoueur + INTERVAL (EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM dobjoueur)) YEAR))    AS reste1
                    ,   ABS(CURRENT_DATE - (dobjoueur + INTERVAL (EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM dobjoueur) - 1) YEAR)) AS reste2
                    ,   ABS(CURRENT_DATE - (dobjoueur + INTERVAL (EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM dobjoueur) + 1) YEAR)) AS reste3
                FROM    matable
            )   AS  tmp
    WHERE   reste1 <= 1
        OR  reste2 <= 1
        OR  reste3 <= 1
    Je ne conserve pas dans les résultats les personnes dont l'anniversaire est plus lointain qu'un jour.

    PS: A vérifier car je n'ai testé que sur le papier !

Discussions similaires

  1. [VxiR2] Date d'anniversaire année bissextile
    Par Unsurgent dans le forum Webi
    Réponses: 2
    Dernier message: 21/02/2012, 16h11
  2. Réponses: 1
    Dernier message: 07/03/2011, 09h32
  3. [Dates] Liste déroulante date et années bissextiles
    Par Jiraiya42 dans le forum Langage
    Réponses: 7
    Dernier message: 03/07/2007, 01h04
  4. [Dates] Jour Mois anné, heure minute et seconde...
    Par SangKou dans le forum Langage
    Réponses: 4
    Dernier message: 29/11/2005, 09h34
  5. [Date] Problème d'année
    Par nebule dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 13/12/2004, 11h55

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