Como calcular dias habiles incluyendo fines de semana y feriados locales, debo confesar que al al principio se me hizo complicado el asunto pero luego piace of cake.
1.- Pasar la fecha inicial y final a maketime y obtener un arreglo con todas los días intermedios.
function DiasHabiles($fecha_inicial,$fecha_final)
{
list($dia,$mes,$year) = explode("-",$fecha_inicial);
$ini = mktime(0, 0, 0, $mes , $dia, $year);
list($diaf,$mesf,$yearf) = explode("-",$fecha_final);
$fin = mktime(0, 0, 0, $mesf , $diaf, $yearf);
$r = 1;
while($ini != $fin)
{
$ini = mktime(0, 0, 0, $mes , $dia+$r, $year);
$newArray[] .=$ini;
$r++;
}
return $newArray;
}
2.- Una función que evalué el arreglo de fechas obtenido, que contenga los feriados nacionales que correspondan (restando) y que reste los sábados y domingos.
function Evalua($arreglo)
{
$feriados = array(
'1-1', // Año Nuevo (irrenunciable)
'10-4', // Viernes Santo (feriado religioso)
'11-4', // Sábado Santo (feriado religioso)
'1-5', // Día Nacional del Trabajo (irrenunciable)
'21-5', // Día de las Glorias Navales
'29-6', // San Pedro y San Pablo (feriado religioso)
'16-7', // Virgen del Carmen (feriado religioso)
'15-8', // Asunción de la Virgen (feriado religioso)
'18-9', // Día de la Independencia (irrenunciable)
'19-9', // Día de las Glorias del Ejército
'12-10', // Aniversario del Descubrimiento de América
'31-10', // Día Nacional de las Iglesias Evangélicas y Protestantes (feriado religioso)
'1-11', // Día de Todos los Santos (feriado religioso)
'8-12', // Inmaculada Concepción de la Virgen (feriado religioso)
'13-12', // elecciones presidencial y parlamentarias (puede que se traslade al domingo 13)
'25-12', // Natividad del Señor (feriado religioso) (irrenunciable)
);
$j= count($arreglo);
for($i=0;$i<=$j;$i++)
{
$dia = $arreglo[$i];
$fecha = getdate($dia);
$feriado = $fecha['mday']."-".$fecha['mon'];
if($fecha["wday"]==0 or $fecha["wday"]==6)
{
$dia_ ++;
}
elseif(in_array($feriado,$feriados))
{
$dia_++;
}
}
$rlt = $j - $dia_;
return $rlt;
}
3.- Se llama a las funciones.
$CantidadDiasHabiles = Evalua(DiasHabiles('19-10-2010','28-12-2010'));
echo $CantidadDiasHabiles;
Si tiene solución mas simple, favor publiquen.
Saludos
el codigo esta muy interesante pero cuando lo intento poner a prueba me vota un error un la declaracion de la variable $newArray, otro en la variable $dia_ ++ y un undefinied offset en
ResponderEliminar$dia = $arreglo[$i]; me gustaria que me dieras una pronta solucion pues tu codigo me interesa muchisimo pero no lo puedo poner a funcionar de antemano muchas gracias e intentare seguir revisando el codigo por mi cuenta mientras tanto.....
<?php
Eliminar//1.- Pasar la fecha inicial y final a maketime y obtener un arreglo con todas los días intermedios.
function DiasHabiles($fecha_inicial,$fecha_final)
{
$newArray = array();
list($year,$mes,$dia) = explode("-",$fecha_inicial);
$ini = mktime(0, 0, 0, $mes , $dia, $year);
list($yearf,$mesf,$diaf) = explode("-",$fecha_final);
$fin = mktime(0, 0, 0, $mesf , $diaf, $yearf);
$r = 1;
while($ini != $fin)
{
$ini = mktime(0, 0, 0, $mes , $dia+$r, $year);
echo "ini = ". $ini ."
";
$newArray[] .=$ini;
$r++;
}
return $newArray;
}
//2.- Una función que evalué el arreglo de fechas obtenido, que contenga los feriados nacionales que correspondan (restando) y que reste los sábados y domingos.
function Evalua($arreglo)
{
$feriados = array(
'1-1', // Año Nuevo (irrenunciable)
'10-4', // Viernes Santo (feriado religioso)
'11-4', // Sábado Santo (feriado religioso)
'1-5', // Día Nacional del Trabajo (irrenunciable)
'21-5', // Día de las Glorias Navales
'29-6', // San Pedro y San Pablo (feriado religioso)
'16-7', // Virgen del Carmen (feriado religioso)
'15-8', // Asunción de la Virgen (feriado religioso)
'19-9', // Dia Festivo De Prueba EN EL EJEMPLO <-----
'12-10', // Aniversario del Descubrimiento de América
'31-10', // Día Nacional de las Iglesias Evangélicas y Protestantes (feriado religioso)
'1-11', // Día de Todos los Santos (feriado religioso)
'8-12', // Inmaculada Concepción de la Virgen (feriado religioso)
'13-12', // elecciones presidencial y parlamentarias (puede que se traslade al domingo 13)
'25-12', // Natividad del Señor (feriado religioso) (irrenunciable)
);
$j= count($arreglo);
$dia_NoLab = 0;
$dia = 0;
for($i=0;$i<$j;$i++)
{
$dia = $arreglo[$i];
$fecha = getdate($dia);
$feriado = $fecha['mday']."-".$fecha['mon'];
if($fecha["wday"]==0 or $fecha["wday"]==6)
{
$dia_NoLab++;
echo "Dia Fin de Semana ". $feriado ."
";
}
elseif(in_array($feriado,$feriados))
{
$dia_NoLab++;
echo "Dia Festivo dentro del Arreglo de Festivos ". $feriado ."
";
}
}
$rlt = $j - $dia_NoLab;
echo "j= ". $j ." i= ". $i ."
";
return $rlt;
}
me acabo de dar cuenta que los errores no influyen en el resulatdo, solo que son muy molestos y me gustaria que no apareciera...y pues tuve que realizar algunas modificaciones porque mi formato de fecha es yyyy/mm/dd pero no me esta tomando los festivos... no se que hacer por favor ayudame...
ResponderEliminarPara usar en formato yyyy/mm/dd debes modificar las siguientes lineas:
Eliminarlist($dia,$mes,$year) = explode("-",$fecha_inicial);
list($diaf,$mesf,$yearf) = explode("-",$fecha_final);
por
list($year,$mes,$dia) = explode("/",$fecha_inicial);
list($yearf,$mesf,$diaf) = explode("/",$fecha_final);
Felipe, yo necesito hacer lo mismo, pero modifiqué esto y no funcionó.... por favor me podrías ayudar?
Eliminarpuedes poner
ResponderEliminar$dia = $arreglo["$i"];
con las comillas no te saldra la advertencia
MUCHAS GRACIAS POR TODO...ME SIRVIO DE MUCHO EL CODIGO..
ResponderEliminarSaludos, hice algunas modificaciones sobre los errores y trabaja al 100% asi:
ResponderEliminarHola, podrias Publicar por favor las modificaciones que le hiciste a codigo?, se que es un tema viejo pero me urge este script
Eliminaresta bueno el código, cambie los feriados a los de mi país (Bolivia) y funciona al 100%
ResponderEliminarGenial, muchas gracias!
ResponderEliminarUn aporte de mi parte
ResponderEliminar/**
* Metodo getDiasHabiles
*
* Permite devolver un arreglo con los dias habiles
* entre el rango de fechas dado excluyendo los
* dias feriados dados (Si existen)
*
* @param string $fechainicio Fecha de inicio en formato Y-m-d
* @param string $fechafin Fecha de fin en formato Y-m-d
* @param array $diasferiados Arreglo de dias feriados en formato Y-m-d
* @return array $diashabiles Arreglo definitivo de dias habiles
*/
public function getDiasHabiles($fechainicio, $fechafin, $diasferiados = array()) {
// Convirtiendo en timestamp las fechas
$fechainicio = strtotime($fechainicio);
$fechafin = strtotime($fechafin);
// Incremento en 1 dia
$diainc = 24*60*60;
// Arreglo de dias habiles, inicianlizacion
$diashabiles = array();
// Se recorre desde la fecha de inicio a la fecha fin, incrementando en 1 dia
for ($midia = $fechainicio; $midia <= $fechafin; $midia += $diainc) {
// Si el dia indicado, no es sabado o domingo es habil
if (!in_array(date('N', $midia), array(6,7))) { // DOC: http://www.php.net/manual/es/function.date.php
// Si no es un dia feriado entonces es habil
if (!in_array(date('Y-m-d', $midia), $diasferiados)) {
array_push($diashabiles, date('Y-m-d', $midia));
}
}
}
return $diashabiles;
}
Mejor visualizacion aqui: http://pastebin.com/sKkn61L4
EliminarEste comentario ha sido eliminado por el autor.
Eliminarexcelente aportación, funcional, fácil de entender e implementar, gracias!!!
ResponderEliminarmuy buena, era justo lo que buscaba, lo malo es que cuenta un dia menos en cada mes, al final del "Evalua" le agregué un +1 y quedo bien.
ResponderEliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarencontre una forma de calcular los dias habiles entre dos fechas incluyendo los festivos para colombia, como el codigo es largo no le deja pegar todo aqui, pero esta en este lugar
Eliminarhttp://pastebin.com/7pdxKy3z
Perfecto una gran ayuda, yo solo buscaba los dias habiles
ResponderEliminarAsí que tuve que modificar ese código, ademas de corregir las notificaciones que salen de php, la fecha yo la utilizo
YYYY-MM-DD.
Muchas gracias aquí dejare el código resumido en una sola función y una disculpa por modificar muchas cosas:
function buscaDiasHabiles($fecha_inicial,$fecha_final){
list($year,$mes,$dia) = explode("-",$fecha_inicial);
$ini = mktime(0, 0, 0, $mes , $dia, $year);
list($yearf,$mesf,$diaf) = explode("-",$fecha_final);
$fin = mktime(0, 0, 0, $mesf , $diaf, $yearf);
$newArray = array();
$r = 1; $i = 0; $dia2 = 0;
while($ini != $fin){
$ini = mktime(0, 0, 0, $mes , $dia+$r, $year);
$newArray[$i]=$ini;
$r++;$i++;
}
for($i=0;$i<count($newArray); $i++){
$dia = $newArray[$i];
$fecha = getdate($dia);
if($fecha["wday"]==0 or $fecha["wday"]==6){
$dia2++;
}
}
$rlt = count($newArray) - $dia2;
return $rlt;
}
EL codigo se ajustaba a mi necesidad, pero no se porque lo suben con errores, igual ya lo ajuste un poco y le elimine los errores aca les dejo mi codigo
ResponderEliminar";
//1.- Pasar la fecha inicial y final a maketime y obtener un arreglo con todas los días intermedios.
function DiasHabiles($fecha_inicial,$fecha_final)
{
$newArray = array();
list($year,$mes,$dia) = explode("-",$fecha_inicial);
$ini = mktime(0, 0, 0, $mes , $dia, $year);
list($yearf,$mesf,$diaf) = explode("-",$fecha_final);
$fin = mktime(0, 0, 0, $mesf , $diaf, $yearf);
$r = 1;
while($ini != $fin)
{
$ini = mktime(0, 0, 0, $mes , $dia+$r, $year);
echo "ini = ". $ini ."
";
$newArray[] .=$ini;
$r++;
}
return $newArray;
}
//2.- Una función que evalué el arreglo de fechas obtenido, que contenga los feriados nacionales que correspondan (restando) y que reste los sábados y domingos.
function Evalua($arreglo)
{
$feriados = array(
'1-1', // Año Nuevo (irrenunciable)
'10-4', // Viernes Santo (feriado religioso)
'11-4', // Sábado Santo (feriado religioso)
'1-5', // Día Nacional del Trabajo (irrenunciable)
'21-5', // Día de las Glorias Navales
'29-6', // San Pedro y San Pablo (feriado religioso)
'16-7', // Virgen del Carmen (feriado religioso)
'15-8', // Asunción de la Virgen (feriado religioso)
'19-9', // Dia Festivo De Prueba EN EL EJEMPLO <-----
'12-10', // Aniversario del Descubrimiento de América
'31-10', // Día Nacional de las Iglesias Evangélicas y Protestantes (feriado religioso)
'1-11', // Día de Todos los Santos (feriado religioso)
'8-12', // Inmaculada Concepción de la Virgen (feriado religioso)
'13-12', // elecciones presidencial y parlamentarias (puede que se traslade al domingo 13)
'25-12', // Natividad del Señor (feriado religioso) (irrenunciable)
);
$j= count($arreglo);
$dia_NoLab = 0;
$dia = 0;
for($i=0;$i<$j;$i++)
{
$dia = $arreglo[$i];
$fecha = getdate($dia);
$feriado = $fecha['mday']."-".$fecha['mon'];
if($fecha["wday"]==0 or $fecha["wday"]==6)
{
$dia_NoLab++;
echo "Dia Fin de Semana ". $feriado ."
";
}
elseif(in_array($feriado,$feriados))
{
$dia_NoLab++;
echo "Dia Festivo dentro del Arreglo de Festivos ". $feriado ."
";
}
}
$rlt = $j - $dia_NoLab;
echo "j= ". $j ." i= ". $i ."
";
return $rlt;
}
?>
No me funciona :(
EliminarSi quisiera sacar el primer día hábil, incluyendo de manera manual los festivos.. Cómo seria? tendría que meter los festivos en un array, pero como?
modify('first day of this month');
echo $fecha->format('d');
echo $fecha->format('m');
echo $fecha->format('Y');
echo "
";
echo "
";
$fecha->modify('last day of this month');
echo $fecha->format('d');
echo $fecha->format('m');
echo $fecha->format('Y');
>?
No me funciona ningún código, me faltarà algo? help¡
ResponderEliminarhttps://gist.github.com/angelmartz/7694083
ResponderEliminar