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 ?
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 ?
vous pouvez utiliser une expression régulière pour analyser cette chaine. comme cela par exemple :
pour plus d'informations sur les expressions régulières, vous pouvez regarder là :
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"
https://regex101.com/r/EIQE2j/1
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); } ?>
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
Donc ça marcherait si tu avais mois et jours, mais il faut quand même convertir les semaines à la fin
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 $interval = new DateInterval("P1W6D"); echo $interval->format('%d jours'); // renvoie 6 jours![]()
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]
je vous mets un code de ninja :
attention, ça fonctionne !
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![]()
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);
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.
On peut aussi faire ça:ou avec php 7.4:
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; });
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);
Partager