PHP Arrotondamento minuti in differenza tra due Orari

Discussione in 'PHP' iniziata da MATTIAVANNI, 12 Marzo 2019.

  1. MATTIAVANNI

    MATTIAVANNI Nuovo Utente

    Registrato:
    12 Marzo 2019
    Messaggi:
    4
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    Salve a tutti,
    vi scrivo per chiedervi il vostro aiuto:

    volevo crearmi il cartellino degli orari di lavoro con calcolo differenza ingresso ed uscita arrotondato alla mezz'ora, ho copiato da web questo codice, ma avrei bisogno di modificare il risultato alla mezz'ora, cioè mi spiego meglio con un esempio:
    PHP:
    <?php
    $mattinoingresso 
    "5:52";
    $mattinouscita "14:05";

    function 
    differenza($prima,$seconda){
        
    $p=explode(":"$prima);
        
    $s=explode(":"$seconda);
        
    $prima_sec=$p[0]*60*60 $p[1]*60 $p[2];
        
    $seconda_sec=$s[0]*60*60 $s[1]*60 $s[2];
        
    $diff_sec=abs($prima_sec $seconda_sec);
        
    $dif_ore=(int)($diff_sec/3600);
        
    $resto=$diff_sec-$dif_ore*3600;
        
    $dif_minuti=(int)($resto/60);
        
    $dif_secondi=abs($diff_sec-$dif_ore*3600-$dif_minuti*60);
        
    $dif_ore=($dif_ore<10 "0" "").$dif_ore;
        
    $dif_minuti=($dif_minuti<10 "0" "").$dif_minuti;
        
    $dif_secondi=($dif_secondi<10 "0" "").$dif_secondi;
        return 
    "$dif_ore:$dif_minuti";
    };
    echo 
    $MATTINA = @differenza($mattinoingresso,$mattinouscita) . " ore lavorate<br />\n";
    ?>
    il risultato mi da 8.13 ma vorrei che se sotto i 30 minuti diventasse 8.00 e se sopra i 30 minuti diventasse 8.30

    come posso fare?

    grazie in anticipo!!!
     
    Ultima modifica di un moderatore: 12 Marzo 2019
  2. Max 1

    Max 1 Super Moderatore Membro dello Staff SUPER MOD MOD

    Registrato:
    29 Febbraio 2012
    Messaggi:
    3.770
    Mi Piace Ricevuti:
    283
    Punteggio:
    83
    Sesso:
    Maschio
    @MATTIAVANNI
    Da regolamento del forum, come tutti noi sei tenuto ad usare il tag [​IMG] o il tag [​IMG] per il PHP, quando posti del codice, oppure la funzione codice dalla barra degli strumenti
    [​IMG]
    Inoltre ti prego di leggere attentamente il regolamento generale del forum e quello di sezione dove posti
    Grazie
    Per questa volta te lo sistemo io ma mi raccomando per il futuro
     
  3. marino51

    marino51 Utente Attivo

    Registrato:
    28 Febbraio 2013
    Messaggi:
    2.518
    Mi Piace Ricevuti:
    123
    Punteggio:
    63
    Occupazione:
    free lance
    Località:
    Lombardia
    vedi se é sufficiente così,
    PHP:
    function differenza($in$out)
    {
        
    $dataIN  "2000-01-01 " $in  ":00";
        
    $dataOUT "2000-01-01 " $out ":00";

        if (
    $dataIN $dataOUT)
        {
            
    $dataOUT "2000-01-02 " $out ":00";  // night shift
        
    }

        
    $in  = new DateTime($dataIN);
        
    $out = new DateTime($dataOUT);

        
    $diff $out->diff($in);

        
    $h $diff->h;
        
    $m $diff->i;

        
    $minLavorati $h 60 $m;

        if ( 
    $minLavorati >= 510 ) return "8:30"; else
        if ( 
    $minLavorati >= 480 ) return "8:00"; else
        return 
    $h ":" substr("00".$m, -2);
    }
    con questo risultato

    upload_2019-3-12_15-38-28.png
     
    A MATTIAVANNI piace questo elemento.
  4. MATTIAVANNI

    MATTIAVANNI Nuovo Utente

    Registrato:
    12 Marzo 2019
    Messaggi:
    4
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    Ciao Marino, grazie mille per l'aiuto.

    il mio problema è che le ore lavorate potrebbero essere anche 4 o 6 o 10 al giorno...
    mi succede inserendo alcuni orai che mi riporta oltre all'orario anche i minuti come nel tuo ultimo risultato 21:25 - 05:05 - 7:13ore lavorate...

    io avrei bisogno che mi arrotondasse sempre per difetto, cioè sopra i 30 minuti a $h.30 e sotto i trenta minuti a $h. 00, calcolando la mezz'ora in più solo se effettivamente lavorata e non come somma tra i minuti di ingresso e quelli in uscita...
     
  5. macus_adi

    macus_adi Utente Attivo

    Registrato:
    5 Dicembre 2017
    Messaggi:
    882
    Mi Piace Ricevuti:
    49
    Punteggio:
    28
    Sesso:
    Maschio
    Occupazione:
    Developer
    Località:
    L'Aquila
    Riutilizzando lo script di sopra e aggiungendo una funzione che verifica la "prossimità", modificherei così:
    PHP:
    function my_round(&$data,$precision=30){

       (
    $precision-$data>=0)?$data='00':$data=$precision;

    }

    function 
    differenza($in$out)
    {
       
    $dataIN  "2000-01-01 " $in  ":00";
       
    $dataOUT "2000-01-01 " $out ":00";

       if (
    $dataIN $dataOUT)
       {
          
    $dataOUT "2000-01-02 " $out ":00";  // night shift
       
    }

       
    $in  = new DateTime($dataIN);
       
    $out = new DateTime($dataOUT);

       
    $diff $out->diff($in);

       
    $h $diff->h;
       (
    $diff->i<10)?$m='0'.$diff->i:$m=$diff->i;
       
    my_round($m);

       return 
    'orario originale:'.$diff->h.':'.$diff->i.' Orario calcolato: '$h.':'.$m;
    }
    echo 
    differenza('15:05','18:41');
    echo 
    "\r\n";
    echo 
    differenza('15:05','18:11');
    Dovrebbe essere quello che cerchi!

    NB: si nota un piccolo baco in "diff->i" se < 10,risolto con la funzione my_round!
     
    Ultima modifica: 12 Marzo 2019
    A MATTIAVANNI piace questo elemento.
  6. MATTIAVANNI

    MATTIAVANNI Nuovo Utente

    Registrato:
    12 Marzo 2019
    Messaggi:
    4
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    Ciao Macus, grazie mille per l'aiuto.

    Ora mi funziona perfettamente e mi conteggia correttamente il minutaggio a 0 oppure a 30, solo in un caso però mi sbaglia il calcolo se uso
    Codice:
    differenza('20:30','22:00');
    non mi legge la mezzora
     
  7. macus_adi

    macus_adi Utente Attivo

    Registrato:
    5 Dicembre 2017
    Messaggi:
    882
    Mi Piace Ricevuti:
    49
    Punteggio:
    28
    Sesso:
    Maschio
    Occupazione:
    Developer
    Località:
    L'Aquila
    Provato con il codice che ti ho postato e correttamente torna 1:30 se deve tornare 1:00 basta passare alla funzione my_round precision a 31
     
  8. MATTIAVANNI

    MATTIAVANNI Nuovo Utente

    Registrato:
    12 Marzo 2019
    Messaggi:
    4
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    ho provato ma non mi da la mezzora

    PHP:
    <?php
    $in 
    "20:30";
    $out "24:00";


    function 
    my_round(&$data,$precision=31){

       (
    $precision-$data>=0)?$data='00':$data=$precision;

    }

    function 
    differenza($in$out)
    {
       
    $dataIN  "2000-01-01 " $in  ":00";
       
    $dataOUT "2000-01-01 " $out ":00";

       if (
    $dataIN $dataOUT)
       {
          
    $dataOUT "2000-01-02 " $out ":00";  // night shift
       
    }

       
    $in  = new DateTime($dataIN);
       
    $out = new DateTime($dataOUT);

       
    $diff $out->diff($in);

       
    $h $diff->h;
       (
    $diff->i<10)?$m='0'.$diff->i:$m=$diff->i;
       
    my_round($m);

       return 
    $h.':'.$m;
    }
    echo 
    differenza($in,$out);
    ?>
     
  9. macus_adi

    macus_adi Utente Attivo

    Registrato:
    5 Dicembre 2017
    Messaggi:
    882
    Mi Piace Ricevuti:
    49
    Punteggio:
    28
    Sesso:
    Maschio
    Occupazione:
    Developer
    Località:
    L'Aquila
    Precision = 30 e
    precision - data >0 (togli =)

    Prova anche questa dovrebbe andare per il tuo scopo.... è possibile definire la prossimità con relativo scarto da utilizzare per scopi futuri......
    PHP:
    /**
    * Created by PhPS.
    * User: MADR
    * Date: 13/03/2019
    * Time: 08:16
    */

    namespace MADR;


    class 
    Rounded {

       public 
    $date_in='';

       public 
    $date_out='';

       private 
    $c_round=
          [
             
    '00'=>[0,29],
             
    '30'=>[30,60]
          ];

       private 
    $result=[];

       public 
    $output=[];


       public function 
    __construct($params=[]) {
          foreach (
    $params as $k=>$v){
             (
    property_exists($this,$k))?$this->$k=$v:null;
          }
       }

       public static function 
    RRounding(){
          return (new 
    Rounded());
       }



       public function 
    setCround($p){
          
    $this->c_round=$p;
          return 
    $this;
       }

       public function 
    setIn($p){
          
    $this->date_in=$p;
          return 
    $this;
       }
       public function 
    setOut($p){
          
    $this->date_out=$p;
          return 
    $this;
       }

       public function 
    diffDate(){
          
    $this->vDate($this->date_in)->vDate($this->date_out);
          
    $this->date_in=new \DateTime($this->date_in);
          
    $this->date_out=new \DateTime($this->date_out);
          
    $this->result=$this->date_out->diff($this->date_in);
          
    $this->rounding()->set_output();
          return 
    $this;
       }


       public function 
    rounding(){
          foreach (
    $this->c_round as $k=>$v){
             if(
    $this->result->i>=$v[0] && $this->result->i<=$v[1]){
                
    $this->result->cal_min=$k;

                
    $this->result->min_min=$this->result->i-$v[0];
                return 
    $this;
             }
          }
       }

       private function 
    set_output(){
          
    $this->output=
             [
                
    'input'=>
                   [
                      
    'ingresso'=>$this->date_in,
                      
    'uscita'=>$this->date_out
                   
    ],
                
    'natural'=>
                   [
                      
    'ore'=>$this->result->h,
                      
    'minuti'=>$this->result->i
                   
    ],
                
    'calcolato'=>
                   [
                      
    'ore'=>$this->result->h,
                      
    'minuti'=>$this->result->cal_min
                   
    ],
                
    'arrotondamento'=>$this->result->min_min
             
    ];
          return 
    $this;
       }

       private function 
    vDate(&$date){
          
    $dt = \DateTime::createFromFormat('Y-m-d H:i:s'$date);
          (empty(
    $dt))?$date=date('Y-m-d',time()).' '.$date:$date=$dt;
          return 
    $this;
       }
    }

    print_r(Rounded::RRounding()->setIn('20:15')->setOut('23:46')->diffDate()->output);
    L'output è di questo genere:
    Codice:
    Array
    (
        [input] => Array
            (
                [ingresso] => DateTime Object
                    (
                        [date] => 2019-03-13 20:15:00.000000
                        [timezone_type] => 3
                        [timezone] => UTC
                    )
                [uscita] => DateTime Object
                    (
                        [date] => 2019-03-13 23:46:00.000000
                        [timezone_type] => 3
                        [timezone] => UTC
                    )
            )
        [natural] => Array
            (
                [ore] => 3
                [minuti] => 31
            )
        [calcolato] => Array
            (
                [ore] => 3
                [minuti] => 30
            )
        [arrotondamento] => 1
    )
    
     
    Ultima modifica: 13 Marzo 2019
    A MATTIAVANNI piace questo elemento.
  10. marino51

    marino51 Utente Attivo

    Registrato:
    28 Febbraio 2013
    Messaggi:
    2.518
    Mi Piace Ricevuti:
    123
    Punteggio:
    63
    Occupazione:
    free lance
    Località:
    Lombardia
    leggo ora ….
    avevo capito che lavorassi con le otto ore, ma mi sembra che, qualunque siano le ore lavorate devi sempre arrotondare i minuti allo zero (zero - ventinove) o a trenta (trenta - cinquantanove)

    in questo caso, mantenendo semplicità nel codice,
    PHP:
    function differenza($in$out)
    {
        
    $dataIN  "2000-01-01 " $in  ":00";
        
    $dataOUT "2000-01-01 " $out ":00";

        if (
    $dataIN $dataOUT)
        {
            
    $dataOUT "2000-01-02 " $out ":00";  // night shift
        
    }

        
    $dtIN  = new DateTime($dataIN);
        
    $dtOUT = new DateTime($dataOUT);

        
    $diff $dtOUT->diff($dtIN);

        
    $h $diff->h;
        
    $m substr("00".$diff->i, -2);

        
    $tL $h.":".$m;

        
    $mRes = ( $m 30 "00" "30" );

        
    $tC $h ":" $mRes;

        echo 
    "ingresso = " $in " uscita = " $out " lavorato = " $tL " calcolato = " $tC "<br />";

        return 
    $tC;
    }
    ottengo questo risultato

    upload_2019-3-13_10-22-44.png

    per le prove,
    PHP:
    differenza("05:52""14:05");
    differenza("13:52""22:05");
    differenza("21:52""06:05");
    differenza("21:52""07:05");
    differenza("21:52""05:05");
    differenza('15:05''18:41');
    differenza('15:05''18:11');
    differenza('20:30''22:00');
     
    Ultima modifica: 13 Marzo 2019
    A MATTIAVANNI piace questo elemento.
Sto caricando...

Condividi questa Pagina