Pregunta

Quiero calcular la cantidad de días de la semana en un mes y año determinados.Días de semana significa de lunes a viernes.¿Cómo lo hago?

¿Fue útil?

Solución

Un código básico:

$month = 12;
$weekdays = array();
$d = 1;

do {
    $mk = mktime(0, 0, 0, $month, $d, date("Y"));
    @$weekdays[date("w", $mk)]++;
    $d++;
} while (date("m", $mk) == $month);

print_r($weekdays);

Elimine @ si su advertencia de error de PHP no muestra avisos.

Otros consejos

No es necesario contar todos los días del mes.Ya sabes que los primeros 28 días contienen 20 días de la semana sin importar qué.Todo lo que tienes que hacer es determinar los últimos días.Cambie el valor inicial a 29. Luego agregue 20 días de la semana a su valor de retorno.

function get_weekdays($m,$y) {
$lastday = date("t",mktime(0,0,0,$m,1,$y));
$weekdays=0;
for($d=29;$d<=$lastday;$d++) {
    $wd = date("w",mktime(0,0,0,$m,$d,$y));
    if($wd > 0 && $wd < 6) $weekdays++;
    }
return $weekdays+20;
}

prueba este

function getWeekdays($m, $y = NULL){
    $arrDtext = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri');

    if(is_null($y) || (!is_null($y) && $y == ''))
        $y = date('Y');

    $d = 1;
    $timestamp = mktime(0,0,0,$m,$d,$y);
    $lastDate = date('t', $timestamp);
    $workingDays = 0;
    for($i=$d; $i<=$lastDate; $i++){
        if(in_array(date('D', mktime(0,0,0,$m,$i,$y)), $arrDtext)){
            $workingDays++;
        }
    }
    return $workingDays;
}

Este es el código más simple que se me ocurrió. Realmente necesitaría crear una matriz o una tabla de base de datos para celebrar las vacaciones y obtener un recuento real de "Días laborables", pero eso no fue lo que se pidió, así que aquí tiene, espero que esto ayude a alguien.

function get_weekdays($m,$y) {
$lastday = date("t",mktime(0,0,0,$m,1,$y));
$weekdays=0;
for($d=1;$d<=$lastday;$d++) {
    $wd = date("w",mktime(0,0,0,$m,$d,$y));
    if($wd > 0 && $wd < 6) $weekdays++;
    }
return $weekdays;
}

Obtenga el número de días laborables sin festivos entre dos fechas:

Ejemplo de uso:

echo number_of_working_days('2013-12-23', '2013-12-29');

Salida:

3

Enlace a la función

Método DateObject:

function getWorkingDays(DateTime $date) {
    $month = clone $date;
    $month->modify('last day of this month');
    $workingDays = 0;
    for ($i = $month->format('t'); $i > 28; --$i) {
        if ($month->format('N') < 6) {
            ++$workingDays;
        }
        $month->modify('-1 day');
    }

    return 20 + $workingDays;
}

Calcule los días laborables en un mes a partir de cualquier fecha:

public function getworkd($mday)
{
    $dn = new DateTime($mday);
    $dfrom = $dn->format('Y-m-01');
    $dtill = $dn->format('Y-m-t');
    $df = new DateTime($dfrom);
    $dt = new DateTime($dtill);
    $wdays = 0;
    while($df<=$dt)
    {
        $dof= $df->format('D') ;
        if( $dof == 'Sun' || $dof == 'Sat' ) ; else $wdays++;
        $df->add(new DateInterval('P1D'));
    }
    return $wdays;
}

Busque el último día y el día de la semana del mes especificado
luego haz un ciclo while simple como: -

$dates = explode(',', date('t,N', strtotime('2013-11-01')));
$day = $dates[1]; 
$tot = $dates[0]; 
$cnt = 0;
while ($tot>1)
{   
    if ($day < 6)
    {   
        $cnt++;
    }   
    if ($day == 1)
    {   
        $day = 7;
    }   
    else
    {   
        $day--;
    }   
    $tot--;
}

$ cnt= total del día de la semana (de lunes a viernes) de un mes determinado

Se me ocurrió una función sin bucle.Mucho mejor en términos de rendimiento.Puede parecer complicado, pero solo necesita preguntarle a PHP el primer día de la semana y el número de días del mes: el resto son operaciones aritméticas basadas en la lógica.

function countWorkDays($year, $month)
{
    $workingWeekdays   = 5;
    $firstDayTimestamp = mktime(0, 0, 0, $month, 1, $year);
    $firstDayWeekDay   = (int)date("N", $firstDayTimestamp); //1: monday, 7: saturday
    $upToDay           = (int)date("t", $firstDayTimestamp);

    $firstMonday = 1 === $firstDayWeekDay ? 1 : 9 - $firstDayWeekDay;
    $wholeWeeks  = $firstMonday < $upToDay ? (int)floor(($upToDay - $firstMonday + 1) / 7) : 0;
    $extraDays   = ($upToDay - $firstMonday + 1) % 7;

    $initialWorkdays      = $firstMonday > 1 && $firstDayWeekDay <= $workingWeekdays ? $workingWeekdays - $firstDayWeekDay + 1 : 0;
    $workdaysInWholeWeeks = $wholeWeeks * $workingWeekdays;
    $extraWorkdays        = $extraDays <= $workingWeekdays ? $extraDays : $workingWeekdays;

    return $initialWorkdays + $workdaysInWholeWeeks + $extraWorkdays;
}

Estas funciones funcionan sin bucles .

Las funciones calculan el número de días de la semana usando:

  • día-número del primer lunes del mes
  • número de días del mes
// main functions 
// weekdays in month of year
function calculateNumberOfWeekDaysAtDate($month, $year)
{
    // I'm sorry, I don't know the right format for the $month and $year, I hope this is right.
    // PLEASE CORRECT IF WRONG
    $firstMondayInCurrentMonth = (int) date("j", strtotime("first monday of 01-$month-$year")); //get first monday in month for calculations
    $numberOfDaysOfCurrentMonth = (int) date("t", strtotime("01-$month-$year")); // number of days in month

    return calculateNumberOfWeekDaysFromFirstMondayAndNumberOfMonthDays($firstMondayInCurrentMonth, $numberOfDaysOfCurrentMonth);
}

// week days in current month
function calculateNumberOfWeekDaysInCurrentMonth()
{
    $firstMondayInCurrentMonth = (int) date("j", strtotime("first monday of this month")); //get first monday in month for calculations
    $numberOfDaysOfCurrentMonth = (int) date("t"); // number of days in this month

    return calculateNumberOfWeekDaysFromFirstMondayAndNumberOfMonthDays($firstMondayInCurrentMonth, $numberOfDaysOfCurrentMonth);
}

// helper functions
function calculateNumberOfWeekDaysFromFirstMondayAndNumberOfMonthDays($firstMondayInCurrentMonth, $numberOfDaysOfCurrentMonth)
{
    return $numberOfWeekDays = (($start = ($firstMondayInCurrentMonth - 3)) < 0 ? 0 : $start) + floor(($numberOfDaysOfCurrentMonth - ($firstMondayInCurrentMonth - 1)) / 7) * 5 + (($rest = (($numberOfDaysOfCurrentMonth - ($firstMondayInCurrentMonth - 1)) % 7)) <= 5 ? $rest : 5);
}
function workingDays($m,$y) {
    $days = cal_days_in_month(CAL_GREGORIAN, $m, $y);
    $workig_days = 0;
    $days_rest = array(5,6); //friday,saturday
    for ( $d=1 ; $d < $days+1 ; $d++ ) {
        if ( !in_array(date("w",strtotime("{$d}-{$m}-{$y}")),$days_rest)  ) {
            $workig_days++;
        }
    }
    return $workig_days;
}

esto funcionará

// oct. 2013
$month = 10;

// loop through month days
for ($i = 1; $i <= 31; $i++) {

    // given month timestamp
    $timestamp = mktime(0, 0, 0, $month, $i, 2012);

    // to be sure we have not gone to the next month
    if (date("n", $timestamp) == $month) {

        // current day in the loop
        $day = date("N", $timestamp);

        // if this is between 1 to 5, weekdays, 1 = Monday, 5 = Friday
        if ($day == 1 OR $day <= 5) {

            // write it down now
            $days[$day][] = date("j", $timestamp);
        }
    }
}

// to see if it works :)
print_r($days);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top