Calcolo giorni lavorativi tra due date (escluse le feste comandate)

Maures

Utente Attivo
25 Mar 2015
45
0
0
Buongiorno a tutti,
devo creare uno script per il calcolo dei giorni lavorativi fra due date.
Sfruttando questo codice sono riuscito nel mio intento, ma ora mi si pone un problema.
Come potete vedere, il codice inserisce manualmente in un array le feste, costringendo poi il programmatore a modificarle di volta in volta ogni anno. inoltre se dovessi fare il calcolo a cavallo di due anni, non funzionerebbe. come rendere dinamico questo array?
Come aggiungo a questo array anche la pasqua, che non è mai nello stesso giorno?

Grazie a tutti.
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.042
149
63
PR
www.borgo-italia.it
ciao
questa considera festivi solo il sabato e la domenica
se vuoi anche le altre devi farti un array con le date delle feste (es 25/04, 01/06....)
poi con date("d/m",$timestamp) verifichi che non sia sabato o domenica ma se festa decrementi
il problema l'hai con la data di pasqua variabile di anno in anno

PHP:
<?php
function giorni_lav($d1,$d2){
	$d_i=explode("-",$d1);//attento al formato delle date che hai tu
	$d_f=explode("-",$d2);
	$d_i_ts=mktime(0,0,0,$d_i[1],$d_i[0],$d_i[2]);//espressa in secondi TIME STAMP
	$d_f_ts=mktime(0,0,0,$d_f[1],$d_f[0],$d_f[2]);
	$g_ts= 24*60*60;//secondi in un giorno
	$quanti_giorni=(int)(($d_f_ts-$d_i_ts)/$g_ts-1);//giorni totali compresi i festivi
	while($d_i_ts < $d_f_ts){
		//7=domenica, 6=sabato
		if(date("N",$d_i_ts)== '6' || date("N",$d_i_ts)== '7'){
			$quanti_giorni -= 1;// se trovo un sabato o una domenica decremento l'intervallo
		}
		$d_i_ts +=$g_ts;//incrementa l'iniziale di un giorno
	}
	return $quanti_giorni;
}
// test
$data_inizio="01-06-2015";
$data_fine="13-06-2015";
echo "giornate lavorative ".giorni_lav($data_inizio,$data_fine);
//OUTPUT giornate lavorative 9
?>
 

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
Ciao, anche il lunedi di pasqua è festa. credo
Puoi provare a calcolarlo con questa funzione.
Secondo me nel link che hai postato, la seconda soluzione che hanno proposto ( number_of_working_days() ) si adatta meglio alle tue esigenze ed è molto più semplice da modificare. Necessita però di php 5.3.0 o superiore visto l'utilizzo della classe DateTime()
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.042
149
63
PR
www.borgo-italia.it
ciao
criric ha ragione, che cada di domenica la pasqua è risaputo e quindi basterebbe calcolarla come domenica, ma anche lunedì è festivo e quindi da determinare quindi secondo me si dovrebbe:
determinare la datqa della pasqua e aggiungere un giorno
verificare se la pasqua cade tra le due date richieste e togliere dai lavorativi il lunedi
se ti interessa vado a ripescare una funzione che avevo fatto e che calcolava la data per ogni anno con l'algoritomo di gaus

@criric
la funzione number_of_working_days() non credo che consideri le festività locali e quindi secondo me da fare sempre un array con tali date
 

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
Si l'array delle festività locali è inevitabile.
Avevo iniziato a buttar gìù un idea ma poi mi sono bloccato, posto la bozza incompleta
PHP:
function Pasqua($anno) {

    $nc = intval($anno / 100);
    $nn = $anno - 19 * intval($anno / 19);
    $nk = intval(($nc - 17) / 25);
    $ni1 = $nc - intval($nc / 4) - intval(($nc - $nk) / 3) + 19 * $nn + 15;
    $ni2 = $ni1 - 30 * intval($ni1 / 30);
    $ni3 = $ni2 - intval($ni2 / 28) * (1 - intval($ni2 / 28) * intval(29 / ($ni2 + 1)) * intval((21 - $nn) / 11));
    $nj1 = $anno + intval($anno / 4) + $ni3 + 2 - $nc + intval($nc / 4);
    $nj2 = $nj1 - 7 * intval($nj1 / 7);
    $nl = $ni3 - $nj2;

    $mese = 3 + intval(($nl + 40) / 44);
    $giorno = $nl + 28 - 31 * intval($mese / 4);

    return $anno . "-" . $mese . "-" . $giorno;
}

function festivo($data = false) {

    $check = new DateTime();
    if (!$check->createFromFormat('Y-m-d', $data)) {
        return "data non valida";
    }

    $d = new DateTime($data);
    $pasqua = new DateTime(Pasqua($d->format("Y")));

    $festivita = array(
        "01-01" => "Capodanno",
        "01-06" => "Epifania",
        "04-25" => "Festa della liberazione",
        $pasqua->format("m-d") => "Pasqua",
        $pasqua->modify("+1 day")->format("m-d") => "Lunedi' dell'Angelo",
        "05-01" => "Festa dei lavoratori",
        "06-02" => "Festa della repubblica",
        "08-15" => "Ferragosto",
        "11-01" => "Festa di tutti i santi",
        "12-08" => "Festa dell'immacolata",
        "12-25" => "Natale",
        "12-26" => "Giorno di Santo Stefano"
    );
    if (!$data) {
        return $festivita;
    }
    if (array_key_exists($d->format('m-d'), $festivita)) {
        return $festivita[$d->format('m-d')];
    }
    if ($d->format('w') == 0) {
        return "Domenica";
    }

    return false;
}

var_dump(festivo(date("Y-m-d")));
edit:
ops, avevo troncato, cmq ho sbagliato script
 
Ultima modifica:

marino51

Utente Attivo
28 Feb 2013
3.041
192
63
Lombardia
vedi se ti va bene,
ciao
Marino

PHP:
<?php
  $holidayDays = 
  [
    "*-01-01"=>"Capodanno",
    "*-01-06"=>"Epifania", 
    "*-04-25"=>"Liberazione", 
    "*-05-01"=>"Festa Lavoratori", 
    "*-06-02"=>"Festa della Repubblica", 
    "*-08-15"=>"Ferragosto", 
    "*-11-01"=>"Tutti Santi", 
    "*-12-08"=>"Immacolata", 
    "*-12-25"=>"Natale", 
    "*-12-26"=>"Santo Stefano",
    "*-08-16"=>"Patrono"
  ];

$DataInizio	= '2015-01-01';
$DataFine	= '2015-12-31';

$AnnoInizio	= date('Y', strtotime($DataInizio));
Pasqua($AnnoInizio);
$holidayDays[$AnnoInizio."-".$Lmese."-".$Lgiorno] = "Pasquetta ".$AnnoInizio;

$AnnoFine	= date('Y', strtotime($DataFine));
if($AnnoFine != $AnnoInizio) {
  Pasqua($AnnoFine);
  $holidayDays[$AnnoFine."-".$Lmese."-".$Lgiorno] = "Pasquetta ".$AnnoFine;
}
echo $DataInizio." --> ".$DataFine."<br /><br />";
echo "number_of_working_days = ".number_of_working_days($DataInizio, $DataFine, $holidayDays)."<br /><br />";
print_r ($holidayDays);


function number_of_working_days($from, $to, $holidayDays, $workingDays = [1, 2, 3, 4, 5]) 
{
  $holidayDays = array_flip($holidayDays);

  $from = new DateTime($from);
  $to = new DateTime($to);
  $to->modify('+1 day');
  $interval = new DateInterval('P1D');
  $periods = new DatePeriod($from, $interval, $to);

  $days = 0;
  foreach ($periods as $period) {
    if (!in_array($period->format('N'),   $workingDays)) continue;
    if ( in_array($period->format('Y-m-d'), $holidayDays)) continue;
    if ( in_array($period->format('*-m-d'), $holidayDays)) continue;
    $days++;
  }
  return $days;
}

function Pasqua($anno) { 
  global $Pmese,$Pgiorno,$Lmese,$Lgiorno; 

  $nc=intval($anno/100); 
  $nn=$anno-19*intval($anno/19); 
  $nk=intval(($nc-17)/25); 
  $ni1=$nc-intval($nc/4)-intval(($nc-$nk)/3)+19*$nn+15; 
  $ni2=$ni1-30*intval($ni1/30); 
  $ni3=$ni2-intval($ni2/28)*(1-intval($ni2/28)*intval(29/($ni2+1))*intval((21-$nn)/11)); 
  $nj1=$anno+intval($anno/4)+$ni3+2-$nc+intval($nc/4); 
  $nj2=$nj1-7*intval($nj1/7); 
  $nl=$ni3-$nj2; 

  $Pmese=3+intval(($nl+40)/44); 
  $Pgiorno=$nl+28-31*intval($Pmese/4); 

  if ($Pmese == 3 and $Pgiorno == 31) { $Lmese = 4; $Lgiorno = 1; } 
  else { $Lmese = $Pmese; $Lgiorno = $Pgiorno + 1; } 
} 
?>

Codice:
2015-01-01 --> 2015-12-31

number_of_working_days = 255

Array ( [*-01-01] => Capodanno [*-01-06] => Epifania [*-04-25] => Liberazione [*-05-01] => Festa Lavoratori [*-06-02] => Festa della Repubblica [*-08-15] => Ferragosto [*-11-01] => Tutti Santi [*-12-08] => Immacolata [*-12-25] => Natale [*-12-26] => Santo Stefano [*-08-16] => Patrono [2015-4-6] => Pasquetta 2015 )
 
Discussioni simili
Autore Titolo Forum Risposte Data
MarcoGrazia Calcolo fra due date con esclusione delle feste PHP 7
M calcolo della velocità MS Access 5
C scelta operazione di calcolo in c++ C/C++ 7
Alex_70 Calcolo eta' da fixare PHP 60
M Problema con php per calcolo costo percentuale PHP 7
claudio_lorenzo [Javascript] aiuto su jquery per calcolo altezze dom Javascript 1
A [PHP] calcolo numero di ore effettuate PHP 7
M [Javascript] Verifica calcolo prima di fare insert Javascript 13
M [PHP] Visualizzare nell'alert il calcolo PHP 4
maxnegri [PHP]Funzione di calcolo prezzo di una camera in un range di date PHP 62
N [Java] Piccolo jform per calcolo totale da 2 campi i double Java 0
S Creare un foglio di calcolo in html collegandolo a un e-commerce HTML e CSS 7
P [PHP] Calcolo prezzi camera in range di date diverse PHP 11
V calcolo giorno di fine mese ad una seconda data jQuery 0
matteoraggi VPS specifica per calcolo ffmpeg Server Dedicati e VPS 1
M [Javascript] Calcolo sbagliato Javascript 7
Z [PHP] Calcolo giorno PHP 5
S [PHP] Calcolo Rate PHP 2
T [PHP] Calcolo anzianità soggetti [era: Help me :( Esercizio per me impossibile] PHP 9
asevenx [Javascript] aggiungere righe con select da database e calcolo sconto in automatico Javascript 0
Bunz [Javascript] somma orario input + calcolo straordinario Javascript 3
andrea.peo Calcolo differenza fra record attivo e precedente PHP 1
M calcolo iva da valore di un form PHP 2
U calcolo imc Javascript 1
D Creare script per calcolo ore PHP 11
S calcolo php PHP 2
E calcolo date feriali Database 6
G Calcolo differenza valori provenienti da una tabella PHP 0
jacobous Calcolo Mediana MS Access 4
felino Quesito matematico: calcolo ore stimate avendo la percentuale. Discussioni Varie 24
S Analysis Service 2005 calcolo incidenza Database 0
scatenato calcolo input PHP 1
A Checkbox da db e calcolo delle variabili Java 1
D calcolo fra date php PHP 2
scatenato aiuto:calcolo automatico dei campi input Javascript 7
M php / mysql calcolo prezzo base preventivo per hotel PHP 34
P Problemi di calcolo tra due date PHP 37
F calcolo percorso google map PHP 0
M [REGIME dei MINIMI] Plusvalenza fuori dal calcolo dei 30.000 euro Leggi, Normative e Fisco 1
filippino Calcolo IVA con javascript Javascript 3
L calcolo distanza tra due punti geografici Sviluppo app per iOS 0
L Calcolo della percentuale PayPal che varia in base al totale. E-Commerce 1
radioButton Qual è la capacita di calcolo di un database? Database 9
N [risolto] Funzione per calcolo età PHP 4
P Risorse di calcolo java Java 1
Emix errore nel calcolo PHP 4
M Importare pagine database pubblico in foglio di calcolo OpenOffice Windows e Software 0
G Aiutino su un calcolo javascript in tempo reale Javascript 15
Emix Doppio form con calcolo variabili PHP 5
P problemi calcolo prezzo PHP 19

Discussioni simili