Pagina 1 di 10 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 97
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    360

    Conteggio giorni tra 2 date e Daylight Saving Time (DST)

    Salve,

    ho necessitò di conteggiare il numero di giorni tra 2 date, non riesco a trovare lo snippet migliore che tenga conto del Daylight Saving Time (DST).

    Nel database ho le date nel formato YYYY-MM-DD.

    Mi
    sto perdendo nel materiale che trovo sul web e vorrei da voi qualche indicazione su quale effettivamente mi può portare al risultato.

    Una volta conteggiato
    il numero di giorni tra 2 date, devo poter calcolare i giorni compresi a cavallo di più mesi, mi spiego meglio, scrivo nel formato italiano

    30-05-2016
    02-06-2016
    Devo ottenere il calcolo appunto di 3 notti
    Devo però
    ottenere anche un secondo calcolo che mi indica che sono 2 notti nel mese di maggio e 1 notte nel mese di giugno, come fare?

    Grazie!

  2. #2
    Moderatore di PHP L'avatar di Alhazred
    Registrato dal
    Oct 2003
    Messaggi
    12,469
    Devi ragionare su ciò che ti mette a disposizione la funzione date(), che tra le altre cose ti dice se una certa data è soggetta a DST o no usando il parametro I (i maiuscola), per la differenza in giorni puoi usare la funzione date_diff().
    Avendo a disposizione queste funzioni, il calcolo è solo questione di logica.

  3. #3
    Utente di HTML.it
    Registrato dal
    Apr 2011
    residenza
    Arezzo
    Messaggi
    194
    Che ne dici di una cosa del genere?
    magari è da migliorare....


    Codice PHP:
    $differenza calcolaNotti('2016-05-30','2016-06-02');

    var_dump($differenza);


    function 
    calcolaNotti($checkIn,$checkOut)
    {
        
    // usare formato yyyy-mm-dd
        // la funzione restituisce un array('notti'=>'tot','mese'=>'notti','mese'=>'notti',........);
        // seconto quanti mesi vengono esaminati
        
        
    $mesi = ['01'=>'Gen','02'=>'Feb','03'=>'Mar','04'=>'Apr','05'=>'Mag','06'=>'Giu',
                    
    '07'=>'Lug','08'=>'Ago','09'=>'Set','10'=>'Ott','11'=>'Nov','12'=>'Dic'];
        
        
    $giornoIn substr($checkIn,7,2);
        
    $meseIn substr($checkIn,5,2);
        
    $annoIn substr($checkIn,0,4);
        
        
    $giornoOut substr($checkOut,7,2);
        
    $meseOut substr($checkOut,5,2);
        
    $annoOut substr($checkOut,0,4);
        
        
    $result = [];

        
    // calcola la differenza totale
        
    $checkIn1 date_create($checkIn);
        
    $checkOut1 date_create($checkOut);
        
    $diff date_diff($checkIn1$checkOut1);
        
    $totNotti $diff->format('%a');
        
    $result['notti'] = $totNotti;
        
        
        
    // funzione che calcola diff per mese
        
    function finemese($data)
        {
            
    $split split('-'$data);
            
    $day $split[2];
            
    $month $split[1];
            
    $year $split[0];
            
            
    $res true;
            
    $count 0;
            while(
    $res)
            {
                
    $check checkdate($month$day$year);
                if(
    $check)
                {
                    
    $day++;
                    
    $count++;
                    
    $res true;
                }
                else{
    $res false;}
            }
            
            return 
    $count;
        }
        
        
        
    // restituisce i giorni per ogni mese
        
    $mesiToccati $meseOut $meseIn;
        if(
    $mesiToccati 1)
        {
            
    $giorno $giornoIn;
            for(
    $i=1$i==$mesiToccati$i++)
            {
                
    $nottiMese finemese($annoIn.'-'.$i.'-'.$giorno);
                
    $nomeMese $mesi[$i];
                
                
    $result[$nomeMese] = $nottiMese;
                
                
    $giorno 0;
            }
            
            
    $nomeMeseOut $mesi[$meseOut];
            
            
    $result[$nomeMeseOut] = $giornoOut 1;
        }
        else
        {
            
    $nottiMese1 finemese($checkIn);
            
    $nomeMese1 $mesi[$meseIn];
            
            
    $nottimese2 $totNotti $nottiMese1;
            
    $nomeMese2 $mesi[$meseOut];
            
            
    $result[$nomeMese1] = $nottiMese1;
            
    $result[$nomeMese2] = $nottimese2;
        }
        
        return 
    $result;

    Riccardo Sadocchi
    Microsoft MCP C#

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    360
    rikyeko grazie! Per migliorare che cosa intendi, sa già se non va qualche cosa? E' OK per DST? Io ancora non ho analizzato tutto il codice, quindi chiedo direttamente a te. Quindi calcola sia le notti e fa anche la suddivisione tra i mesi? Come estrai questi 2 valori?

  5. #5
    Utente di HTML.it
    Registrato dal
    Apr 2011
    residenza
    Arezzo
    Messaggi
    194
    Migliorare si può sempre migliorare tutto... era per dire

    ti basta passare due date alla funzione, la prima il check-in, la seconda il check-out, e ti restituisce un array con il primo valore il totale delle notti, e poi tanti valori per quanti mesi vengono intaccati nell'intervallo delle date.

    Nel caso di 2016-05-30 -> 2016-06-02 la funzione restituisce

    array(3) { ["notti"]=> string(1) "3" ["Mag"]=> int(2) ["Giu"]=> int(1) }

    Forse l'unico problema potrebbe esserci se le date sono a cavallo tra due anni
    Ultima modifica di rikyeko; 12-05-2016 a 13:44
    Riccardo Sadocchi
    Microsoft MCP C#

  6. #6
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    360
    Bene!

    Io ho delle prenotazioni, registrate con il check in e check out nel db, il tuo sistema mi sembra ottimo quando si lavora con una data, ma dovendo fare questi calcoli per più prenotazioni e poi fare:

    - il conteggio dei giorni per ogni singola prenotazione
    - contare quanti giorni liberi rimangono per ogni mese sottraendo appunto i giorni prenotati

    il problema maggiore è il fatto delle date a cavallo tra mesi, come potrei ciclare questi calcoli? Il sistema tiene conto del Daylight Saving Time (DST)?

    Ti ringrazio in anticipo perché lavoro con il PHP di rado e vedendo il tuo snippet ho pensato che tu abbia realizzato un qualche cosa di simile alle mie necessità, almeno l'ambiente di utilizzo, quello delle prenotazioni, mi sembra proprio quello.

    Andrebbe valutato come tu dici quando ci si trova a cavallo di anni.

    In verità il conteggio delle notti sono riuscito a farlo con jQuery, ma visto che necessito di altri calcoli, preferisco sfruttare PHP.

    Grazie!

  7. #7
    Utente di HTML.it
    Registrato dal
    Apr 2011
    residenza
    Arezzo
    Messaggi
    194
    In realtà la funzione l'ho buttata giù quando ho letto il tuo post, non ho niente di pronto, ho intuito che parlavi di prenotazioni in quanto ti riferivi a notti...

    Ho provato e a cavallo di due anni funziona bene, quello che non funziona è se il calcolo interessa più di due mesi
    (es. 2016-05-30 -> 2016-08-05), questo è proprio da rivedere, anzi rifare.

    il DST è praticamente automatico, nell'ultimo mese basta prendere il giorno di out - 1 (es. out il 15 sono 14 notti)
    Riccardo Sadocchi
    Microsoft MCP C#

  8. #8
    Utente di HTML.it
    Registrato dal
    Apr 2011
    residenza
    Arezzo
    Messaggi
    194
    Dunque, così funziona:

    Codice PHP:
    $differenza calcolaNotti('2016-05-30','2016-08-02');

    var_dump($differenza);

    function 
    calcolaNotti($checkIn,$checkOut)
    {
        
    // usare formato yyyy-mm-dd
        // la funzione restituisce un array('notti'=>'tot','mese'=>'notti','mese'=>'notti',........);
        // seconto quanti mesi vengono esaminati
        
        
    $mesi = ['01'=>'Gen','02'=>'Feb','03'=>'Mar','04'=>'Apr','05'=>'Mag','06'=>'Giu',
                    
    '07'=>'Lug','08'=>'Ago','09'=>'Set','10'=>'Ott','11'=>'Nov','12'=>'Dic'];
        
        
    $giornoIn substr($checkIn,8,2);
        
    $giornoOut substr($checkOut,8,2);
        
        
    $meseIn substr($checkIn,5,2);
        
    $meseOut substr($checkOut,5,2);

        
    $annoIn substr($checkIn,0,4);

        
    $result = [];

        
    // calcola la differenza totale
        
    $checkIn1 date_create($checkIn);
        
    $checkOut1 date_create($checkOut);
        
    $diff date_diff($checkIn1$checkOut1);
        
    $totNotti $diff->format('%a');
        
    $result['notti'] = $totNotti;
        
        
    // funzione che calcola diff per mese
        
    function finemese($data)
        {
            
    $split split('-'$data);
            
    $day $split[2];
            
    $month $split[1];
            
    $year $split[0];
            
            
    $res true;
            
    $count 0;
            while(
    $res)
            {
                
    $check checkdate($month$day$year);
                if(
    $check)
                {
                    
    $day++;
                    
    $count++;
                    
    $res true;
                }
                else{
    $res false;}
            }
            
            return 
    $count;
        }
        
        
    // restituisce i giorni per ogni mese
        
    $mOut = (int)$meseOut;
        
    $mIn = (int)$meseIn;
        
    $mesiToccati $mOut $mIn;
        if(
    $mesiToccati 1)
        {
            
    $giorno $giornoIn;
            
    $start = (int)substr($checkIn,5,2);
            
    $end = (int)substr($checkOut,5,2);
            for(
    $i=$start$i<$end$i++)
            {
                if(
    $i<10){$ii = (string)'0'.$i;}
                else{
    $ii = (string)$i;}
                
    $nottiMese finemese($annoIn.'-'.$ii.'-'.$giorno);
                
    $nomeMese $mesi[$ii];
                
    $result[$nomeMese] = $nottiMese;
                
    $giorno '01';
            }
            
    $nomeMeseOut $mesi[$meseOut];
            
    $result[$nomeMeseOut] = ((int)$giornoOut) - 1;
        }
        else
        {
            
    $nottiMese1 finemese($checkIn);
            
    $nomeMese1 $mesi[$meseIn];
            
            
    $nottimese2 $totNotti $nottiMese1;
            
    $nomeMese2 $mesi[$meseOut];
            
            
    $result[$nomeMese1] = $nottiMese1;
            
    $result[$nomeMese2] = $nottimese2;
        }
        
        return 
    $result;

    passando come check-in 2016-05-30 e check-out 2016-08-02 ti restituisce un array così

    array(5) { ["notti"]=> string(2) "64" ["Mag"]=> int(2) ["Giu"]=> int(30) ["Lug"]=> int(31) ["Ago"]=> int(1) }
    Riccardo Sadocchi
    Microsoft MCP C#

  9. #9
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    360
    Per il DTS, quando dici "nell'ultimo mese basta prendere il giorno di out", per ultimo mese cosa intendi?

    E quando si è a cavallo di 2 anni, come distinguerli?

    Idee invece per quello che dicevo per calcolare ciclicamente per più prenotazioni presenti nel DB e calcolare quindi giorni prenotati e giorni disponibili per ogni mese di un anno?
    Ultima modifica di harry80; 12-05-2016 a 15:34

  10. #10
    Utente di HTML.it
    Registrato dal
    Apr 2011
    residenza
    Arezzo
    Messaggi
    194
    intanto.... ulteriore correzione, non avevo considderato se le date sono nello stesso mese...

    Codice PHP:
    function calcolaNotti($checkIn,$checkOut)
    {
        
    // usare formato yyyy-mm-dd
        // la funzione restituisce un array('notti'=>'tot','mese'=>'notti','mese'=>'notti',........);
        // seconto quanti mesi vengono esaminati
        
        
    $mesi = ['01'=>'Gen','02'=>'Feb','03'=>'Mar','04'=>'Apr','05'=>'Mag','06'=>'Giu',
                    
    '07'=>'Lug','08'=>'Ago','09'=>'Set','10'=>'Ott','11'=>'Nov','12'=>'Dic'];
        
        
    $giornoIn substr($checkIn,8,2);
        
    $giornoOut substr($checkOut,8,2);
        
        
    $meseIn substr($checkIn,5,2);
        
    $meseOut substr($checkOut,5,2);

        
    $annoIn substr($checkIn,0,4);

        
    $result = [];

        
    // calcola la differenza totale
        
    $checkIn1 date_create($checkIn);
        
    $checkOut1 date_create($checkOut);
        
    $diff date_diff($checkIn1$checkOut1);
        
    $totNotti $diff->format('%a');
        
    $result['notti'] = $totNotti;
        
        
    // funzione che calcola diff per mese
        
    function finemese($data)
        {
            
    $split split('-'$data);
            
    $day $split[2];
            
    $month $split[1];
            
    $year $split[0];
            
            
    $res true;
            
    $count 0;
            while(
    $res)
            {
                
    $check checkdate($month$day$year);
                if(
    $check)
                {
                    
    $day++;
                    
    $count++;
                    
    $res true;
                }
                else{
    $res false;}
            }
            
            return 
    $count;
        }
        
        
    // restituisce i giorni per ogni mese
        
    $mOut = (int)$meseOut;
        
    $mIn = (int)$meseIn;
        
    $mesiToccati $mOut $mIn;
        if(
    $mesiToccati 1)
        {
            
    $giorno $giornoIn;
            
    $start = (int)substr($checkIn,5,2);
            
    $end = (int)substr($checkOut,5,2);
            for(
    $i=$start$i<$end$i++)
            {
                if(
    $i<10){$ii = (string)'0'.$i;}
                else{
    $ii = (string)$i;}
                
    $nottiMese finemese($annoIn.'-'.$ii.'-'.$giorno);
                
    $nomeMese $mesi[$ii];
                
    $result[$nomeMese] = $nottiMese;
                
    $giorno '01';
            }
            
    $nomeMeseOut $mesi[$meseOut];
            
    $result[$nomeMeseOut] = ((int)$giornoOut) - 1;
        }
        elseif(
    $mesiToccati==1)
        {
            
    $nottiMese1 finemese($checkIn);
            
    $nomeMese1 $mesi[$meseIn];
            
            
    $nottimese2 $totNotti $nottiMese1;
            
    $nomeMese2 $mesi[$meseOut];
            
            
    $result[$nomeMese1] = $nottiMese1;
            
    $result[$nomeMese2] = $nottimese2;
        }
        
        return 
    $result;

    Riccardo Sadocchi
    Microsoft MCP C#

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.