[RESOLU] Fonction de prise en compte des jours fériés en php

Petit nouveau ! | 8 Messages

14 nov. 2015, 12:40

Bonjour,
Dans le cadre du développement d'une application WEB, je propose à mes agents de poser leurs jours de congés. Je souhaitais ne pas déduire les jours fériés ainsi que les week-end (samedi - dimanche).
J'ai trouvé une fonction permettant de gérer les jours fériés fixes et mouvants. Voici le code :
<?php
    function isNotWorkable($date)
    {
 
          if ($date === null)
          {
            $date = time();
          }
 
         $date = strtotime(date('m/d/Y',$date));
 
         $year = date('Y',$date);
 
        $easterDate  = easter_date($year);
        $easterDay   = date('j', $easterDate);
        $easterMonth = date('n', $easterDate);
        $easterYear   = date('Y', $easterDate);
 
        $holidays = array(
        // Dates fixes
        mktime(0, 0, 0, 1,  1,  $year),  // 1er janvier
        mktime(0, 0, 0, 5,  1,  $year),  // Fête du travail
        mktime(0, 0, 0, 5,  8,  $year),  // Victoire des alliés
        mktime(0, 0, 0, 7,  14, $year),  // Fête nationale
        mktime(0, 0, 0, 8,  15, $year),  // Assomption
        mktime(0, 0, 0, 11, 1,  $year),  // Toussaint
        mktime(0, 0, 0, 11, 11, $year),  // Armistice
        mktime(0, 0, 0, 12, 25, $year),  // Noel
 
        // Dates variables
        mktime(0, 0, 0, $easterMonth, $easterDay + 1,  $easterYear),
        mktime(0, 0, 0, $easterMonth, $easterDay + 39, $easterYear),
        mktime(0, 0, 0, $easterMonth, $easterDay + 50, $easterYear),
        );
 
      return in_array($date, $holidays);
    }
?>
<html>
	<form method="post" action="essai_heure.php" enctype="multipart/form-data">
		<fieldset style='background:#c4ddf1; width:100%; height:160px;'>
			<legend style='background:#9c8d87; color:white; width:60%; height:24px; size: 16px;'>Validation</legend>
				<!-- Date début des vacances -->
				<label for 'date_posee' align='right'>Date Souhaitée</label><br/>
				<label for 'date_posee' align='right'>Du (inclus) : </label><input type='date' style='background:url("images/design/date.png") #fafafa 10px center no-repeat;width:30%;' name='date_posee_du' id='date_posee_du'  />
				<label for 'date_posee' align='right'>A : </label>
				<select name="time_du" id='time_du' style='#fafafa 10px center no-repeat;width:15%; text-align: right; height: 20%;'>
					<option value="08:00:00">8h00</option>
					<option value="12:00:00">12h00</option>
				</select><br/>
				<!-- Date fin des vacances -->
				<label for 'date_posee' align='right'>Au (inclus) : </label><input type='date' style='background:url("images/design/date.png") #fafafa 10px center no-repeat;width:30%;' name='date_posee_au' id='date_posee_au'  />
				<label for 'date_posee' align='right'>A : </label>
				<select name="time_au" id='time_au' style='#fafafa 10px center no-repeat;width:15%; text-align: right; height: 20%;'>
					<option value="12:00:00">12h00</option>
					<option value="17:30:00">17h30</option>
				</select><br/>
				<!-- Nombre de jours -->
				<!-- Ce nombre de jour est à vérifier au travers du décompte -->
				<label for 'vacances_posees' align='right'>Nombre Jours Décomptés : </label><input type='number' style='background:url("images/design/numero.png") #fafafa 10px center no-repeat;width:20%;' name='vacances_posees' id='vacances_posees' min='0' max='<?php echo $vacDroit;?>' />
				<input type="submit" name="enregistrer_vac" value="Enregistrer" />
				<input type="submit" value="Retour"  onclick="history.go(-2)" />
		</fieldset>
	</form>
</html>
<?php
if (!empty($_POST['enregistrer_vac'])){
	echo "Les vacances du : ".$_POST['date_posee_du']." a ".$_POST['time_du']."<br/>";
	echo "Les vacances du : ".$_POST['date_posee_au']." a ".$_POST['time_au']."<br/>";
	echo "Nombre de jours pris : ".$_POST['vacances_posees']."<br/>";
	// Mise en forme des dates pour insertion table "absence_personnel"
	$date_debut_vacances= date("Y-m-d H:i:s", strtotime($_POST['date_posee_du']." ".$_POST['time_du']));
	$date_fin_vacances=date("Y-m-d H:i:s", strtotime($_POST['date_posee_au']." ".$_POST['time_au']));
	$date_premier_jour_vac=date("Y-m-d", strtotime($_POST['date_posee_du']));
	$id_agent=2;
	$nom_agent="XXXXX XXXXXXXXXXXX";
	// Appel de la fonction pour vérifier les jours posés
	// A ce stade, je ne vérifie que le premier jour
	// Je ferais une boucle foreach pour traiter tous les jours posés
	if(isNotWorkable(date("Y-m-d H:i:s", strtotime($_POST['date_posee_du']." ".$_POST['time_du'])))){
		echo 'Nous sommes un jour férié !! Apéro !!';
    }else{
		echo 'Nous sommes un jour normal, au boulot :p';
    }
 
	// Connexion à la base de données
	include("menu//chiens.php");
	$req = $bdd->prepare('INSERT INTO `absence_personnel` (`ID_AGENT`,`NOM_AGENT`,`DATE_DEBUT_VACANCES`, `DATE_FIN_VACANCES`,`NOMBRE_JOURS_POSES`) VALUES(:id_agent, :nom_agent, :date_debut_vacances, :date_fin_vacances, :nombre_jours_poses)');
	$req->execute(array('id_agent'=>$id_agent, 'nom_agent'=>$nom_agent, 'date_debut_vacances'=>$date_debut_vacances, 'date_fin_vacances'=>$date_fin_vacances, 'nombre_jours_poses'=>$nombre_jours_poses));
	/*Messages d'erreur de validation*/
	$bdd ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
}
else{
	echo "il faut saisir un truc";
}
?>
J'ai bien l'insertion dans la table mais j'ai le message suivant :
Notice: A non well formed numeric value encountered in C:\Program Files (x86)\EasyPHP-DevServer-14.1VC9\data\localweb\projects\GestParq_Version1.1\essai_heure.php on line 10

Je ne comprends pas. J'ai modifié le format de la date, j'ai changé le DateTime rien n'y fait. J'ai toujours ce message qui s'affiche.

Auriez vous une solution ?

Par avance merci.

Mammouth du PHP | 2703 Messages

14 nov. 2015, 17:27

la doc
"Les dates aux formats m/d/y ou d-m-y sont analysées en regardant le séparateur entre les différentes parties : si le séparateur est un slash (/), alors le format américain m/d/y est supposé ; si le séparateur est un tiret (-) ou un point (.), alors le format Européen d-m-y sera supposé. Si toutefois l'année est fournie sur deux digits, et que le séparateur est un tiret (-), la date sera analysée comme étant au format y-m-d.

Pour éviter des ambiguïtés éventuelles, le mieux est d'utiliser le format ISO 8601 (YYYY-MM-DD) ou encore d'utiliser la méthode DateTime::createFromFormat() lorsque c'est possible. "

l'appel de la fonction :
if(isNotWorkable(date("Y-m-d H:i:s", strtotime($_POST['date_posee_du']." ".$_POST['time_du'])))){

Petit nouveau ! | 8 Messages

07 déc. 2015, 23:56

Bonjour,
Pour ceux qui auraient besoin de cette fonction :
<?php
function calcul_nombre_jour($date_debut,$date_fin,$time_debut,$time_fin)
{
    $year = date('Y',strtotime($date_debut));
	$easterDate=easter_date($year);
	$paques=strtotime("+1 day", $easterDate);// Paques
	$ascenssion=strtotime("+39 day", $easterDate); // Ascenssion
	$pentecotes=strtotime("+50 day", $easterDate);// Pentecotes
	$nouvel_an=strtotime("".$year."-01-01");// 1er janvier
	$feteTravail=strtotime("".$year."-05-01");// Fete du travail
	$victoireAllies=strtotime("".$year."-05-08");// Victoire des allies
	$fetenat=strtotime("".$year."-07-14");// Fete nationale
	$assomption=strtotime("".$year."-08-15");// Assomption
	$toussaint=strtotime("".$year."-11-01");// Toussaint
	$armistice=strtotime("".$year."-11-11");// Armistice
	$noel=strtotime("".$year."-12-25");// Noel
	// Redéfinir les dates de début et de fin période
	$time_start=$time_debut;
	$time_end=$time_fin;
	// Traitement si la date de début est égale à la date de fin
	if ($date_debut==$date_fin){
		// On crée un tableau de dates
		$tabDecompte[]=strtotime($date_debut);
		// On définit le nombre de jours décomptés
		if (($time_debut=="08:00:00" and $time_fin=="12:00:00") or ($time_debut=="12:00:00" and $time_fin=="17:30:00")){
		$nombre_jours_poses=0.5;
		}
		else{
		$nombre_jours_poses=1;	
		}
		// Redéfinir les dates de début et de fin période
		$time_start=$time_debut;
		$time_end=$time_fin;
		$extractFirstDate=$date_debut;
		$extractLastDate=$date_fin;
		// On met la date de début au bon format
		$startDateHoliday=$extractFirstDate." ".$time_start;
		// On met la date de fin au bon format
		$endDateHoliday=$extractLastDate." ".$time_end;		
	}
	else{
		// On ne pose pas de vacances le week-end
			if (date("N",strtotime($date_debut))>5){
				// Par défaut on applique une journée entière si c'est la journée du début 
				$time_start="08:00:00";
			}
			else{
				$time_start=$time_debut;
			}

			if (date("N",strtotime($date_fin))>5){
				// Par défaut on applique une journée entière si c'est la journée de fin 
				$time_end="17:30:00";
			}
			else{
				$time_end=$time_fin;
			}
		//On crée un boucle de filtration des week-end et des jours fériés
		for ($date = strtotime($date_debut); $date <= strtotime($date_fin); $date = strtotime("+1 day", $date)) 
		{
			/* les dimanches et samedi ne sont pas comptabilisés */
			if (date("N",$date)<6){
				// Mise en forme de la date
				$dateCompare=date("Y-m-d", strtotime($date));
				// On extrait les jours fériés
				if ($date!=$paques and $date!=$ascenssion and $date!=$pentecotes and $date!=$nouvel_an and $date!=$feteTravail
					 and $date!=$victoireAllies and $date!=$fetenat and $date!=$assomption and $date!=$toussaint and $date!=$armistice
					  and $date!=$noel){
						// On crée un tableau de dates
						$tabDecompte[]=$date;
				}
			}
		}
		
		// On détermine le nombres de jour à décomptés
		$nombre_jours_poses=count($tabDecompte);
		// On peut afficher les périodes a enregistrer dans la table
		// Transformer la première valeur du tableau associatif
		// Extraire la première date saisie
		$extractFirstDate=date("Y-m-d", ($tabDecompte[0]));
		// Extraire la dernière date saisie 
		$extractLastDate=date("Y-m-d", (end($tabDecompte)));
		// On met la date de début au bon format
		$startDateHoliday=$extractFirstDate." ".$time_start;
		// On met la date de fin au bon format
		$endDateHoliday=$extractLastDate." ".$time_end;
		// On calcul le nombre de jours à décompter
		if ($time_start=="12:00:00"){
			// Si la date de début commence à 12h00
			// On ne décompte qu'une demie-journée
			$nombre_jours_poses=$nombre_jours_poses-0.5;
		}
		if ($time_end=="12:00:00"){
			// Si la date de fin termine à 12h00
			// On ne décompte qu'une demie-journée
			$nombre_jours_poses=$nombre_jours_poses-0.5;
		}
	}
	// Création du tableau à extraire
	$tabReturn=array(
	"TabListeDate"=>$tabDecompte, // Liste des jours dans la période recherchée
	"DateDebut"=>$extractFirstDate, // Date de début au format "Y-m-d"
	"HeureDebut"=>$time_start, // heure de début au "H:i:s"
	"DateHeureDebut"=>$startDateHoliday,// Date de début au format "Y-m-d H:i:s"
	"DateFin"=>$extractLastDate,// Date de fin au format "Y-m-d"
	"HeureFin"=>$time_end,// heure de fin au "H:i:s"
	"DateHeureFin"=>$endDateHoliday,// Date de fin au format "Y-m-d H:i:s"
	"NbreJoursDecomptes"=>$nombre_jours_poses // Nombre de jours décomptés
	);
	// On applique le retour
	return ($tabReturn);	
}
?>
Sujet résolu...

Avatar du membre
Mammouth du PHP | 1564 Messages

10 déc. 2015, 19:54

Merci, sache que tu peux faire directement un return array:

Code : Tout sélectionner

// On applique le retour return array( "TabListeDate"=>$tabDecompte, // Liste des jours dans la période recherchée "DateDebut"=>$extractFirstDate, // Date de début au format "Y-m-d" "HeureDebut"=>$time_start, // heure de début au "H:i:s" "DateHeureDebut"=>$startDateHoliday,// Date de début au format "Y-m-d H:i:s" "DateFin"=>$extractLastDate,// Date de fin au format "Y-m-d" "HeureFin"=>$time_end,// heure de fin au "H:i:s" "DateHeureFin"=>$endDateHoliday,// Date de fin au format "Y-m-d H:i:s" "NbreJoursDecomptes"=>$nombre_jours_poses // Nombre de jours décomptés );