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 PHP Discussion :

Traitement de jour dans une chaine


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    347
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 347
    Par défaut Traitement de jour dans une chaine
    Bonjour

    J’ai une chaine type « 2W 3D » ou « 5D ». D signifie day et W signifie week end
    En gros « 1W6D »signifie 13j (« 13d »). c’est typiquement le résultat que j’aimerais calculer, tout avoir en jour mais je ne réussi pas .

    Vous pourriez m’aider ?

  2. #2
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 694
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 694
    Par défaut
    vous pouvez utiliser une expression régulière pour analyser cette chaine. comme cela par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $entree = "3W103D";
     
    preg_match("/([0-9]*)W([0-9]*)D/", $entree, $resultats);
     
    // $resultats[1] contient "3"
    // $resultats[2] contient "103"
    pour plus d'informations sur les expressions régulières, vous pouvez regarder là :
    https://regex101.com/r/EIQE2j/1

  3. #3
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Salut,
    Citation Envoyé par laclac Voir le message
    J’ai une chaine type « 2W 3D » ou « 5D ». D signifie day et W signifie week end
    Ici W c'est pour Week qui veut dire Semaine et pas week-end qui cible samedi et dimanche.
    1W6D ⇒ 1 semaine + 6 jours

  4. #4
    Membre Expert Avatar de darkstar123456
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2008
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 895
    Par défaut
    Bonjour,

    Si on part effectivement de la logique que W = une week et non un weekend, j'ai fait un script qui fait ce que tu veux faire : https://tests.pierre-roels.com/days-counter/

    Par contre, j'ai utilisé une autre RegEx que celle proposée par @mathieu histoire de faciliter le calcul : #([0-9]+)([^\d])+#
    Et voici ma logique PHP :

    Code php : 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
    <?php
     
    function get_letter_value($letter)
    {
        // Ici on a que W comme différence
        // Cependant, si on considérait la possiblité d'avoir "M" pour Month
        // il faudrait alors mettre un switch() pour les différentes valeurs
        return ($letter === 'W') ? 7 : 1;
    }
     
    if (!empty($_POST['action']) && $_POST['action'] === 'submit') {
        echo '<hr />';
     
        preg_match_all('#([0-9]+)([^\d])+#', $_POST['str'], $matches);
        $total = 0;
        for ($i = 0; $i < count($matches[1]); $i++) {
            // L'index 1 représente le chiffre trouvé
            // L'index 2 est la lettre, on va donc la convertir en multiplicateur numérique
            $total += ($matches[1][$i] * get_letter_value($matches[2][$i]));
        }
        printf('Total de %d jours', $total);
    }
    ?>

  5. #5
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Question bête : ce n'est pas le format natif utilisé par DateInterval ?

    EDIT : après vérification DateInterval n'accepte pas W et D en même temps
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $interval = new DateInterval("P1W6D");
    echo $interval->format('%d jours'); // renvoie 6 jours
    Donc ça marcherait si tu avais mois et jours, mais il faut quand même convertir les semaines à la fin
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  6. #6
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    je vous mets un code de ninja :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $str  = '1W6D';
    $eval = function($s) { return "\$days = {$s};"; };
    eval($eval(strtr($str, ['W' => '*7+', 'D' => ''])));
    echo $days;  // 13
    attention, ça fonctionne !

  7. #7
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    Citation Envoyé par Celira Voir le message
    Question bête : ce n'est pas le format natif utilisé par DateInterval ?
    J'avais pensé à peu prés à la même chose mais en exploitant %a (qui renvoie le nombre de jours total), mais malheureusement, ce nombre de jours total n'est défini que lorsque l'instance de DateInterval provient d'une de date_diff. (du coup c'est pas super pratique).


    Sinon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $str = '1W4D';
     
    $days = preg_replace_callback('~ \A (?: ([0-9]+) W )? (?: ([0-9]+) D )? \z ~x', function ($m) {
        return ($m[1] ?? 0) * 7 + ($m[2] ?? 0);
    }, $str);

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    347
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 347
    Par défaut
    Ah Merci beaucoup.
    Je vais tester tout ca, mais ca semble top.
    Effectviement je me suis trompé W c'est Week et non Week end. Désolé pour cette confusion.
    J'étais partie sur une RegExp egalement mais je suis vraiment pas fort en RegExp. Merci du coup.

    Pour info, Oui c'est pour utilisé dans DateInterval.
    Le probleme est que DateInterval prend soit des W soit des D, mais pas les 2. d'ou mon probleme.
    Je voulais donc tout passer en Day. Merci bien en tout cas, je vous dis si ca marche.

  9. #9
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    On peut aussi faire ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $days = array_reduce(preg_split('~W\K~', $str), function ($c, $i) {
        return $c + (new DateInterval("P$i"))->d;
    });
    ou avec php 7.4:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $days = array_reduce(preg_split('~W\K~', $str), fn($c, $i) => $c + (new DateInterval("P$i"))->d);

Discussions similaires

  1. Réponses: 9
    Dernier message: 23/12/2013, 16h40
  2. Réponses: 9
    Dernier message: 06/11/2007, 12h36
  3. Réponses: 23
    Dernier message: 16/11/2002, 19h41
  4. [TP]lire une ligne de l'ecran et la stocker dans une chaine
    Par Bleuarff dans le forum Turbo Pascal
    Réponses: 26
    Dernier message: 02/07/2002, 10h08
  5. Réponses: 3
    Dernier message: 12/06/2002, 21h15

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