PHP obtiene el número de semana por mes

9 minutos de lectura

PHP obtiene el numero de semana por mes
Brenjt

Entonces tengo un script que devuelve el número de semanas en un mes y año en particular. ¿Cómo puedo tomar un día específico de ese mes y determinar si es parte de la semana 1,2,3,4 o 5 de ese mes?

  • ¿Tiene solo un día o es una fecha con un día y un año?

    – Trevor Arjeski

    2 de mayo de 2011 a las 4:22

  • es una fecha con dia y año

    – Brenjt

    2 de mayo de 2011 a las 4:31

  • será mejor cambiar el nombre del tema de esta pregunta: ¡será mejor encontrar el número de semana de un día en un mes!

    – albanx

    21 de junio de 2012 a las 7:40

  • Si es nuevo en esta pregunta, considere esta frase antes de usar cualquiera de las funciones publicadas.

    – Iiridayn

    31/10/2012 a las 20:54


PHP obtiene el numero de semana por mes
marty

Lo más frustrante que he intentado hacer funcionar, ¡pero aquí está!

<?php

    /**
     * Returns the amount of weeks into the month a date is
     * @param $date a YYYY-MM-DD formatted date
     * @param $rollover The day on which the week rolls over
     */
    function getWeeks($date, $rollover)
    {
        $cut = substr($date, 0, 8);
        $daylen = 86400;

        $timestamp = strtotime($date);
        $first = strtotime($cut . "00");
        $elapsed = ($timestamp - $first) / $daylen;

        $weeks = 1;

        for ($i = 1; $i <= $elapsed; $i++)
        {
            $dayfind = $cut . (strlen($i) < 2 ? '0' . $i : $i);
            $daytimestamp = strtotime($dayfind);

            $day = strtolower(date("l", $daytimestamp));

            if($day == strtolower($rollover))  $weeks ++;
        }

        return $weeks;
    }


    //
    echo getWeeks("2011-06-11", "sunday"); //outputs 2, for the second week of the month
?>

  • WOW, funciona casi perfecto. Solo veo un problema. Cuando cambio el traspaso a sábado, marca el 30 de abril como la sexta semana, pero el 29 como el 5, aunque son las mismas semanas. El 30 es el día de reinversión. Si cambio el rollover al domingo, hace algo similar en mayo para el primer día. Cuenta el 1 de mayo como la segunda semana en lugar de la primera semana.

    – Brenjt

    2 mayo 2011 a las 14:25

  • Hmmmm… Maldición, tan cerca. ¿Tal vez si agregara una pequeña instrucción if para ver si el día de transferencia es el primer día del mes o no? Estoy perplejo.

    – marty

    3 de mayo de 2011 a las 0:08

  • Eso es exactamente lo que pensé. Voy a determinar si el traspaso es el primer día o el último día y haré un ajuste allí. Creo que debería funcionar a partir de eso.

    – Brenjt

    3 mayo 2011 a las 14:45

  • mi +1 no es suficiente para esta respuesta… ¡me salvó el trasero hoy! Gracias

    – fútbol

    10 de marzo de 2012 a las 11:49

  • +1 para la solución original, además de la solución de Abhilash, también me gustaría rendir homenaje sugiriendo usar la fecha (“D”) para $ día y desinfectar el rollover con substr (strtolower ($ rollover), 0,3 ) al comienzo de la función. (Entonces, ‘Monday’, ‘mon’, ‘Monster’ funcionarían como rollover para el lunes)

    –Scott Yang

    24 de julio de 2013 a las 4:02

1646754317 967 PHP obtiene el numero de semana por mes
Iiridayn

Editar: tanto para “línea única”: variables necesarias para evitar el recálculo con el condicional. Lancé un argumento predeterminado mientras estaba en eso.

function weekOfMonth($when = null) {
    if ($when === null) $when = time();
    $week = date('W', $when); // note that ISO weeks start on Monday
    $firstWeekOfMonth = date('W', strtotime(date('Y-m-01', $when)));
    return 1 + ($week < $firstWeekOfMonth ? $week : $week - $firstWeekOfMonth);
}

Tenga en cuenta que weekOfMonth(strtotime('Oct 31, 2011')); regresará 6; algunos meses raros tienen 6 semanas, contrariamente a las expectativas de OP. Enero de 2017 es otro mes con 6 semanas ISO: el domingo 1 cae en la semana del año pasado, ya que las semanas ISO comienzan el lunes.

Para starshine531, para devolver un 0 semana indexada del mes, cambie el return 1 + para return 0 + o return (int).

Para Justin Stayton, durante las semanas que comienzan el domingo en lugar del lunes, usaría strftime('%U' en lugar de date('W'como sigue:

function weekOfMonth($when = null) {
    if ($when === null) $when = time();
    $week = strftime('%U', $when); // weeks start on Sunday
    $firstWeekOfMonth = strftime('%U', strtotime(date('Y-m-01', $when)));
    return 1 + ($week < $firstWeekOfMonth ? $week : $week - $firstWeekOfMonth);
}

Para esta versión, 2017-04-30 ahora está en la semana 6 de abril, mientras que 2017-01-31 ahora está en la semana 5.

  • 2015-12-21 devuelve un 4, pero debería devolver un 3.

    – starshine531

    9 oct 2015 a las 21:18

  • @ starshine531 La semana en el mes se indexa a partir de 1 en lugar de 0; mirando un calendario para diciembre de 2015 con eso en mente, parecería que 4 es el valor correcto.

    – Iiridayn

    10 de octubre de 2015 a las 6:34

  • Manten eso en mente W usa el lunes como el comienzo de la semana, por lo que esto no funcionará si usa el domingo como el comienzo de la semana.

    –Justin Stayton

    4 mayo 2016 a las 17:52

  • probablemente usaría ((int) strftime("%U", $day)) - ((int) strftime("%U", strtotime(date('Y-m-01', $day)))) + 1 entonces, aunque no lo he probado extensamente.

    – Iiridayn

    4 mayo 2016 a las 20:15

  • @JoshMountain sí, date("W", strtotime('2017-01-01)) devoluciones 52. Tendré que agregar un cheque especial para enero, ya que los días pueden caer en la última semana del año anterior. Tampoco se puede usar la aritmética modular simple debido a las “semanas bisiestas”: en.wikipedia.org/wiki/ISO_week_date. Lo actualizaré en los próximos días.

    – Iiridayn

    9 de enero de 2017 a las 22:58

public function getWeeks($timestamp)
{
    $maxday    = date("t",$timestamp);
    $thismonth = getdate($timestamp);
    $timeStamp = mktime(0,0,0,$thismonth['mon'],1,$thismonth['year']);    //Create time stamp of the first day from the give date.
    $startday  = date('w',$timeStamp);    //get first day of the given month
    $day = $thismonth['mday'];
    $weeks = 0;
    $week_num = 0;

    for ($i=0; $i<($maxday+$startday); $i++) {
        if(($i % 7) == 0){
            $weeks++;
        }
        if($day == ($i - $startday + 1)){
            $week_num = $weeks;
        }
      }     
    return $week_num;
}

Hola a todos, he estado luchando durante todo el día tratando de descifrar este código, finalmente lo descubrí, así que pensé en compartirlo con todos ustedes.

todo lo que necesita hacer es poner una marca de tiempo en la función y le devolverá el número de la semana.

Gracias

  • 2015-12-21 produce un 4 en lugar del 3 esperado.

    – starshine531

    9 oct 2015 a las 22:47

  • porque es en la cuarta semana

    – Felipe Csaplar

    28 de octubre de 2015 a las 13:06


  • Mis disculpas, lo que necesitaba era el tercer lunes, pero eso es un poco diferente de lo que hace este código. De hecho, es la cuarta semana.

    – starshine531

    5 de noviembre de 2015 a las 23:29

hay un problema con este método. si la fecha de aprobación (digamos 2012/01/01 que es un domingo) y el día “$rollover” es “domingo”, entonces esta función devolverá 2. donde en realidad es la primera semana. Creo que lo he arreglado en la siguiente función. por favor agregue comentarios para hacerlo mejor.

function getWeeks($date, $rollover)
{
    $cut        = substr($date, 0, 8);
    $daylen     = 86400;
    $timestamp  = strtotime($date);
    $first      = strtotime($cut . "01");   
    $elapsed    = (($timestamp - $first) / $daylen)+1;
    $i          = 1;
    $weeks      = 0;
    for($i==1; $i<=$elapsed; $i++)
    {
        $dayfind        = $cut . (strlen($i) < 2 ? '0' . $i : $i);
        $daytimestamp   = strtotime($dayfind);
        $day            = strtolower(date("l", $daytimestamp));
        if($day == strtolower($rollover))
        {
            $weeks++;  
        }
    } 
    if($weeks==0)
    {
        $weeks++; 
    }
    return $weeks;  
}

1646754318 895 PHP obtiene el numero de semana por mes
Torre

Esta es una solución basada en la solución matemática de sberry pero usando PHP Fecha y hora clase en su lugar.

function week_of_month($date) {
    $first_of_month = new DateObject($date->format('Y/m/1'));
    $day_of_first = $first_of_month->format('N');
    $day_of_month = $date->format('j');
    return floor(($day_of_first + $day_of_month - 1) / 7) + 1;
}

  • No estoy seguro de qué versión de PHP está usando, pero la mía tiene una clase DateTime, pero no una clase DateObject, pero cambiar eso fue fácil. Además, se le debe pasar un objeto DateTime para que funcione. Esta función sería mejor si pudiera aceptar un objeto DateTime o una fecha de cadena.

    – starshine531

    20 mayo 2015 a las 22:25

PHP obtiene el numero de semana por mes
Brenjt

Simplemente copie y pegue el código y pase el mes y el año.

por ejemplo mes=04 año=2013.

Eso es exactamente lo que necesitas.

$mm= $_REQUEST['month'];
$yy= $_REQUEST['year'];
$startdate=date($yy."-".$mm."-01") ;
$current_date=date('Y-m-t');
$ld= cal_days_in_month(CAL_GREGORIAN, $mm, $yy);
$lastday=$yy.'-'.$mm.'-'.$ld;
$start_date = date('Y-m-d', strtotime($startdate));
$end_date = date('Y-m-d', strtotime($lastday));
$end_date1 = date('Y-m-d', strtotime($lastday." + 6 days"));
$count_week=0;
$week_array = array();

for($date = $start_date; $date <= $end_date1; $date = date('Y-m-d', strtotime($date. ' + 7 days')))
{
    $getarray=getWeekDates($date, $start_date, $end_date);
echo "<br>";
$week_array[]=$getarray;
    echo "\n";
$count_week++;

}

// its give the number of week for the given month and year
echo $count_week;
//print_r($week_array);

function getWeekDates($date, $start_date, $end_date)
{
    $week =  date('W', strtotime($date));
    $year =  date('Y', strtotime($date));
    $from = date("Y-m-d", strtotime("{$year}-W{$week}+1"));
    if($from < $start_date) $from = $start_date;

    $to = date("Y-m-d", strtotime("{$year}-W{$week}-6")); 
    if($to > $end_date) $to = $end_date;

$array1 = array(
        "ssdate" => $from,
        "eedate" => $to,
);

return $array1;

   // echo "Start Date-->".$from."End Date -->".$to;
}

for($i=0;$i<$count_week;$i++)
{   
$start= $week_array[$i]['ssdate'];
echo "--";

$week_array[$i]['eedate'];
echo "<br>";
}

PRODUCCIÓN:

week( 0 )=>2013-03-01---2013-03-02

week( 1 )=>2013-03-03---2013-03-09

week( 2 )=>2013-03-10---2013-03-16

week( 3 )=>2013-03-17---2013-03-23

week( 4 )=>2013-03-24---2013-03-30

week( 5 )=>2013-03-31---2013-03-31

  • No estoy seguro de qué versión de PHP está usando, pero la mía tiene una clase DateTime, pero no una clase DateObject, pero cambiar eso fue fácil. Además, se le debe pasar un objeto DateTime para que funcione. Esta función sería mejor si pudiera aceptar un objeto DateTime o una fecha de cadena.

    – starshine531

    20 mayo 2015 a las 22:25

PHP obtiene el numero de semana por mes
Raul Shelke

Este es el fragmento que hice para cumplir con mis requisitos para el mismo. Espero que esto te ayudará.

function getWeek($timestamp) {
 $week_year = date('W',$timestamp);
 $week = 0;//date('d',$timestamp)/7;
 $year = date('Y',$timestamp);
 $month = date('m',$timestamp);
 $day = date('d',$timestamp);
 $prev_month = date('m',$timestamp) -1;
if($month != 1 ){
    $last_day_prev = $year."-".$prev_month."-1";
    $last_day_prev = date('t',strtotime($last_day_prev));
    $week_year_last_mon = date('W',strtotime($year."-".$prev_month."-".$last_day_prev));
    $week_year_first_this = date('W',strtotime($year."-".$month."-1"));
    if($week_year_first_this == $week_year_last_mon){
        $week_diff = 0;
    }
    else{
        $week_diff = 1;
    }
    if($week_year ==1 && $month == 12 ){
    // to handle December's last two days coming in first week of January
        $week_year = 53;
    }
    $week = $week_year-$week_year_last_mon + 1 +$week_diff;
}
else{
 // to handle first three days January coming in last week of December.
    $week_year_first_this = date('W',strtotime($year."-01-1"));
    if($week_year_first_this ==52 || $week_year_first_this ==53){
        if($week_year == 52 || $week_year == 53){
            $week =1;
        }
        else{
            $week = $week_year + 1;
        }
    }
    else{
        $week = $week_year;
    }
}
return $week;

}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad