Classe feuille de temps php5

Soyez le premier à donner votre avis sur cette source.

Snippet vu 14 149 fois - Téléchargée 18 fois

Contenu du snippet

Voici une classe PHP5 pour la gestion de feuille de temps en vue d'effectuer par exemple une estimation de date de fin en jours ouvrés.

Calcul exact des jours ouvrés grâce à 1 Calcul des jours fériés.

Calcul de la date et heure de fin à partir d'une durée de charge en j/h avec nombre à virgules flottantes (optimisation réélle à 1 chiffre après la virgule en paramétrant l'interval minimale [iMinIntervalPeriod] à une valeur > 0.1 ).

Possibilité de paramétrer les jours de repos par défaut samedi dimanche.

Methode de calcul par paramétrage du plus petit interval en j/h par défaut 0.01
La valeur 0.01 ne convient pour des performances optimales => valeur choisie uniquement pour exemple.
[addInterval]

Derniière MAJ Modification de l'init:
Ajout de contrôles pour ne pas saisir n'importe quoi.
Optimisations ajout de methodes privées
En attendant de trouver une autre méthode qui n'utilise pas l'ajout successif d'intervalles pour le calcul

Source / Exemple :


<?php
class WorkingTimeSheet
{
  /**
  @property :int
  @desc :temps écoulé depuis le début de la journée en s

  • /
private $iElapsedTime; /** @property :int @desc : timestamp en cours
  • /
private $iCurrentTimestamp; /** @property :array @desc :Les jours fériés de l'année en cours
  • /
private $aBankHolydays; /** @property :double @desc :Dernière Periode ajoutée
  • /
private $dPeriod; /** @property :array @desc : les jours de la semaine en francophone
  • /
public static $aWDays=array(0=>'Dimanche', 1=>'Lundi', 2=>'Mardi', 3=>'Mercredi', 4=>'Jeudi', 5=>'Vendredi', 6=>'Samedi'); /** @property :array @desc : Les options de configuration à passer dans le constructeur ou à configurer par la methode configureProperties iStartingTimestamp: Timestamp pour la date heure de début définissant également l' Horaire d'ouverture quotidienne. iTimePerDay: duree d'une journée travaillée en seconde sFormat: Format de date pour affichage iEffectiveStartTimestamp : prend en compte l'heure de début effective du calcul dans le cas ou une tache ne commencerait pas au moment de l'ouverture quotidienne inclus dans iStartingTimestamp. bClosedOnClosedDays : Booléen à true si les jours fermés ne sont pas travaillés => true par défaut false sinon aWeeklyClosedDays : Les jours chomés de la semaine Defaut Samedi 6 Dimanche 0
  • /
protected $aOptions=array( 'iStartingTimestamp'=>0, 'iEffectiveStartingTimestamp'=>NULL, 'iTimePerDay'=>28800, 'sFormat'=>'d/m/Y H:i:s', 'bClosedOnClosedDays'=>true, 'aWeeklyClosedDays'=>array(6,0), 'dMinIntervalPeriod'=>0.01); /** @param :mixed @desc : $prop est la propriété à récupérer possible uniquement à l'interieur de la classe
  • /
protected function __get($prop) { if (property_exists(get_class($this),$prop)) return $this->$prop; if (!array_key_exists($prop,$this->aOptions)) throw new Exception(__CLASS__.'::'.__FUNCTION__. ' clé option inexistante '.$prop); return $this->aOptions[$prop]; } /** @param :mixed $prop @param :mixed $value @desc : $prop est la propriété à définir possible uniquement à l'interieur de la classe
  • /
protected function __set($prop,$value) { if (property_exists(get_class($this),$prop)) $this->$prop=$value; if (!array_key_exists($prop,$this->aOptions)) throw new Exception(__CLASS__.'::'.__FUNCTION__. ' clé option inexistante '.$prop); $this->aOptions[$prop]=$value; } /** @param :array $aProps @desc : Configuration des options Possibilité de passer un tableau incomplet à condition que chaque clé existe Les valeurs du tableau non renseignées sont celles configurés par défaut en définition
  • /
public function configureProperties($aProps) { if (!is_array($aProps)) throw new Exception(__CLASS__.'::'.__FUNCTION__. ' paramettre invalide '); foreach($aProps as $key=>$val) { if (!array_key_exists($key,$this->aOptions)) { throw new Exception(__CLASS__.'::'.__FUNCTION__. ' clé option inexistante '.$key); } $this->aOptions[$key]=$val; } } /** @desc : Validation et Initialisation des Propriétés privées ou des propriétés non définies.
  • /
private function validProperties() { //echo '<br/>avant validProp'.(date('H',$this->iEffectiveStartingTimestamp)); if (!is_int($this->iStartingTimestamp)) throw new Exception (__CLASS__.' :: '.__FUNCTION__. ' : Type int attendu L '.__LINE__); if (!is_int($this->iEffectiveStartingTimestamp)&& $this->iEffectiveStartingTimestamp!==NULL) throw new Exception (__CLASS__.' :: '.__FUNCTION__. ' : Type int attendu L '.__LINE__); if (!is_int($this->iTimePerDay)) throw new Exception (__CLASS__.' :: '.__FUNCTION__. ' : Type int attendu L '.__LINE__); if (!is_string($this->sFormat)) throw new Exception (__CLASS__.' :: '.__FUNCTION__. ' : Type string attendu L '.__LINE__); if (!is_bool($this->bClosedOnClosedDays)) throw new Exception (__CLASS__.' :: '.__FUNCTION__. ' : Type bool attendu L '.__LINE__); if (!is_double($this->dMinIntervalPeriod)) throw new Exception (__CLASS__.' :: '.__FUNCTION__. ' : Type double attendu L '.__LINE__); if ($this->dMinIntervalPeriod==0) throw new Exception (__CLASS__.' :: '.__FUNCTION__. ' : 0 interdit '.__LINE__); if ($this->isClosed($this->iCurrentTimestamp)) $this->nextOpenedTimestamp(); if ($this->iEffectiveStartingTimestamp===NULL) $this->iEffectiveStartingTimestamp=$this->iCurrentTimestamp; else $this->iEffectiveStartingTimestamp=mktime( date('H',$this->iEffectiveStartingTimestamp), date('i',$this->iEffectiveStartingTimestamp), date('s',$this->iEffectiveStartingTimestamp), date('m',$this->iCurrentTimestamp), date('d',$this->iCurrentTimestamp), date('Y',$this->iCurrentTimestamp)); //echo '<br/>après validProp'.(date('H',$this->iEffectiveStartingTimestamp)); $this->iElapsedTime=$this->iEffectiveStartingTimestamp-$this->iCurrentTimestamp; $this->iCurrentTimestamp=$this->iEffectiveStartingTimestamp; } /** @param :mixed $mProps optionnel par défaut le timestamp actuel est récupéré @desc : Constructeur Configuration des options
  • /
public function __construct($mProps=NULL) { if ($mProps===NULL) $this->iStartingTimestamp=mktime(); if (is_array($mProps)) { $this->configureProperties($mProps); } else if (is_int($mProps)) $this->iStartingTimestamp=$mProps; $this->iCurrentTimestamp=$this->iStartingTimestamp; $this->buildBankHolidays(); $this->validProperties(); } /** @desc : Affiichage
  • /
public function __toString() { return '<br/>DEBUT SAISI : '. self::$aWDays[date('w',$this->iStartingTimestamp)]. ' '.date($this->sFormat,$this->iStartingTimestamp). '<br/>DEBUT EFFECTIF : '. self::$aWDays[date('w',$this->iEffectiveStartingTimestamp)]. ' '.date($this->sFormat,$this->iEffectiveStartingTimestamp). '<br/>FIN : '. self::$aWDays[date('w',$this->iCurrentTimestamp)]. ' '.date($this->sFormat,$this->iCurrentTimestamp). '<br/>Durée Ecoulée en jour ouvrés: '.$this->dPeriod.'<br/>'; } /** @param int @return int @desc : Donne le temps écoulé depuis la date de début de la WorkTimeSheet Ne pas utiliser
  • /
private function getElapsedTimestampFrom($Timestamp) { return ($Timestamp-$this->iStartingTimestamp); } /** @param int optionnel @desc : Construit le tableau de jours feries
  • /
private function buildBankHolidays($ts=NULL) { if ($ts===NULL) $year=date('Y',$this->iStartingTimestamp); else $year=date('Y',$ts); $this->aBankHolydays=array('Jour de l\'an'=>mktime(0,0,0,1,1,$year), 'Fete du Travail'=>mktime(0,0,0,5,1,$year), 'Armist. 1945'=>mktime(0,0,0,5,8,$year), 'Fete nat'=>mktime(0,0,0,7,14,$year), 'Assomption'=>mktime(0,0,0,8,15,$year), 'Toussaint'=>mktime(0,0,0,11,1,$year), 'Armist. 1918'=>mktime(0,0,0,11,11,$year), 'Noel'=>mktime(0,0,0,12,25,$year)); //pâques $G=$year%19; $C=floor($year/100); $C_4=floor($C/4); $E=floor((8*$C+13)/25); $H=(19*$G+$C-$C_4-$E+15)%30; $K=floor($H/28); $P=floor(29/($H+1)); $Q=floor((21-$G)/11); $I=($K*$P*$Q -1)*$K+$H; $B=floor($year/4)+$year; $J1=$B+$I+2+$C_4-$C; $J2=$J1%7; $R=28+$I-$J2; $day=(int)date('d',(mktime(0,0,0,3,1+$R,$year))); $mth=(int)date('m',(mktime(0,0,0,3,1+$R,$year))); $this->aBankHolydays['Lundi de paques']=mktime(0,0,0,$mth,$day,$year); //ascension $dasc=(int)date('d',(mktime(0,0,0,$mth,$day+38,$year))); $masc=(int)date('m',(mktime(0,0,0,$mth,$day+38,$year))); $this->aBankHolydays['ascension']=mktime(0,0,0,$masc,$dasc,$year); //pentecôte $dasc=(int)date('d',(mktime(0,0,0,$mth,$day+49,$year))); $masc=(int)date('m',(mktime(0,0,0,$mth,$day+49,$year))); $this->aBankHolydays['Lundi de Pentecote']=mktime(0,0,0, $masc,$dasc,$year); } /** @param int @return bool @desc : Indique si un timestamp est un jour fermé
  • /
public function isClosed($ts) { $wdts=(int)date('w',$ts); $ts=mktime(0,0,0,date('m',$ts),date('d',$ts),date('Y',$ts)); $isBankH=in_array($ts,$this->aBankHolydays); $isWklyClosed=in_array($wdts,$this->aWeeklyClosedDays); if(!$isBankH) if ($isWklyClosed && $this->bClosedOnClosedDays===true) return true; if ($this->bClosedOnClosedDays===false && ($isBankH||$isWklyClosed)) return false; if ($isBankH) return true; if (!$isWklyClosed) return false; return true; } /** @param int @desc : Définit l'heure de début d'une tache dans la même journée que la propriété iStartingTimestamp si une autre date est incluse elle n'est pas prise en compte seule l'heure importe.
  • /
public function beginWorkSheetAt($timestamp) { $this->iEffectiveStartingTimestamp=$timestamp; $this->validProperties(); } /** @desc : Positionne le timestamp courant sur la prochaine date d'ouverture sans considérer la date courante
  • /
private function nextOpenedTimestamp() { do { $lastYear = date('Y',$this->iCurrentTimestamp); $this->iCurrentTimestamp=mktime(date('H',$this->iStartingTimestamp), date('i',$this->iStartingTimestamp), date('s',$this->iStartingTimestamp), date('m',$this->iCurrentTimestamp), date('d',$this->iCurrentTimestamp)+1, date('Y',$this->iCurrentTimestamp)); if (date('Y',$this->iCurrentTimestamp) !=$lastYear) $this->buildBankHolidays($this->iCurrentTimestamp); } while ($this->isClosed($this->iCurrentTimestamp)); } /** @desc : Ajoute le plus petit interval de temps possible au timestamp courant
  • /
private function addInterval() { if ($this->iElapsedTime >= $this->iTimePerDay ) { $this->iElapsedTime=0; $this->nextOpenedTimestamp(); } $this->iElapsedTime+=(int)($this->iTimePerDay*$this->dMinIntervalPeriod); $this->iCurrentTimestamp+=(int)($this->iTimePerDay*$this->dMinIntervalPeriod); } /** @param double $days @desc : Ajout du nombre de jours ouvrés en décimal au timestamp courant procède par ajout d'intervalles
  • /
public function addFloatingDays($dDays) { $this->dPeriod=$dDays; $nbOfIntervals=$dDays/$this->dMinIntervalPeriod; while ($nbOfIntervals>0) { $this->addInterval(); $nbOfIntervals--; } } /** @desc : retourne les jours feries
  • /
public function getBankHolydays() { return $this->aBankHolydays; } /** @desc : retourne les jours de repos de la semaine
  • /
public function getWeeklyClosedDays() { return $this->aWeeklyClosedDays; } /** @return int @desc : retourne le timestamp courant
  • /
public function getTimestamp() { return $this->iCurrentTimestamp; } } try { // Exemple de feuille de temps commençant tous les jours à 10:00:00: // l'heure de cette date passée en paramètre est gardée comme // heure d'ouverture quotidienne. // On peut commencer le calcul d'une durée ultérieurement dans cette // journée de debut en passant par la methode beginWorkSheetAt($timestamp) // ou par la clé iEffectiveStartingTimestamp du tableau d'options en parametre $Options=array('iStartingTimestamp'=>mktime(10,0,0,12,25,2007), 'iEffectiveStartingTimestamp'=>mktime(14,0,0), 'iTimePerDay'=>28800, 'sFormat'=>'d/m/Y H:i:s', 'bClosedOnClosedDays'=>true, 'aWeeklyClosedDays'=>array(6,0), 'dMinIntervalPeriod'=>0.1); $WorkTime=new WorkingTimeSheet($Options); // Ex Si La premiere feuille commence à 14 heure le premier jour // configuration possible par le constructeur ou par // configureProperties() //$WorkTime->beginWorkSheetAt(mktime(14,0,0)); // calcul la date de fin $WorkTime->addFloatingDays(5.5); // récuperation des jours fériés $Feries = $WorkTime->getBankHolydays(); $Fermes= $WorkTime->getWeeklyClosedDays(); // récupération du timestamp de fin si besoin. $endTimestamp=$WorkTime->getTimestamp(); // écriture de la date de fin par appel implicite à __toString() echo $WorkTime; foreach ($Feries as $key=> $val) { echo '<br/>'.$key.' : '.WorkingTimeSheet::$aWDays[date('w',$val)]. ' '.date('d/m/Y',$val); } foreach ($Fermes as $val) { echo '<br/> : '.WorkingTimeSheet::$aWDays[$val]; } } catch (Exception $e) { echo $e->getMessage(); } ?>

Conclusion :


Voilà N'hésitez pas à me faire part de possibles bugs

A voir également

Ajouter un commentaire

Commentaires

malalam
Messages postés
10844
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17 -
Hello,

c'est une classe intéressante. Je n'ai pas le temps ce matin de regarder en détail (mais ça a l'air très correctement codé) donc je ne note pas encore et réserve d'autres commentaires pour plus tard :-)
Je voulais juste te corriger sur 2 notions de vocabulaire anglais qui m'ont sautées aux yeux là :-)
On écrit sheet, pas sheat.
Et un jour férié (je ne parle pas du week-end là, mais des jours fériés du genre pâques etc), c'est bank holiday, pas closing day.
Vlà, bonne journée, I'll be back :-)
malalam
Messages postés
10844
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17 -
Et ascension, pas ascenssion. Je m'en vais je m'en vais...:-)
guill76
Messages postés
193
Date d'inscription
mercredi 24 août 2005
Statut
Membre
Dernière intervention
3 juin 2016
-
Salut ouais, c'est bien ce qui me semblait, ça me plaisait pas closingDays
Pour sheat, alors là :)) c'est un joli lapsus et je ne m'en étais vraiment pas aperçu.
Merci
guill76
Messages postés
193
Date d'inscription
mercredi 24 août 2005
Statut
Membre
Dernière intervention
3 juin 2016
-
Les corrections sont faites. Au passage, j'ai confondu ce matin avec shit d'où ma réaction lol.
Sheat voulait en fait dire gaine, pas mal non plus!
Je pense avoir intégrer les remarques du mieux possible, car l'anglais j'essaie, mais sur certains mots, c'est pas toujours simple, le français non plus des fois d'ailleurs :).
gb75
Messages postés
6
Date d'inscription
dimanche 10 février 2008
Statut
Membre
Dernière intervention
1 avril 2008
-
Pour pacque Orthodoxe?

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.