web-dev-qa-db-fra.com

PHP obtenir le numéro de la semaine pour le mois

J'ai donc un script qui renvoie le nombre de semaines d'un mois et d'une année donnés. Comment puis-je prendre un jour spécifique de ce mois et déterminer s'il fait partie de la semaine 1,2,3,4 ou 5 de ce mois?

31
brenjt

La chose la plus frustrante que j'ai jamais essayée de faire travailler - mais la voilà!

<?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
?>
45
Marty

Edit: beaucoup pour "single line" - variables nécessaires pour éviter le recalcul avec le conditionnel. Jeté dans un argument par défaut pendant que j'y étais.

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);
}

Veuillez noter que weekOfMonth(strtotime('Oct 31, 2011')); retournera 6; quelques rares mois ont 6 semaines, contrairement aux attentes de OP. Janvier 2017 est un autre mois avec 6 semaines ISO - le dimanche 1er tombe dans la semaine de l'année dernière, puisque les semaines ISO commencent le lundi.

Pour starshine531 , pour renvoyer une semaine du mois indexée par 0, remplacez return 1 + par return 0 + ou return (int).

Pour Justin Stayton , pour les semaines commençant le dimanche au lieu du lundi, j’utiliserais strftime('%U' au lieu de date('W', comme suit:

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);
}

Pour cette version, 2017-04-30 est maintenant dans la semaine 6 d'avril, alors que 2017-01-31 est maintenant dans la semaine 5.

24
Iiridayn
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;
}

Bonjour à tous, je me suis battu toute la journée pour essayer de comprendre ce code. J'ai finalement compris, donc je pensais le partager avec vous tous.

tout ce que vous avez à faire est de mettre un horodatage dans la fonction, qui vous renverra le numéro de la semaine.

merci

13
Philip csaplar

il y a un problème avec cette méthode. si la date de passage (disons le 2012/01/01, qui est un dimanche) et que le jour "roulement" est "dimanche", cette fonction renverra alors 2. où il s'agira en réalité de la 1ère semaine. Je pense que je l'ai corrigé dans la fonction suivante. s'il vous plaît ajouter des commentaires pour le rendre meilleur.

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;  
}
6
Abhilash

Ceci est une solution basée sur la solution mathématique de sberry mais utilisant plutôt PHP DateTime class.

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;
}
5
Wtower

Il suffit de copier et coller le code et de passer mois et année.

par exemple, mois = 04 année = 2013.

C'est exactement ce dont vous avez besoin.

$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>";
}

SORTIE:

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
4
pratik

Ceci est l'extrait que j'ai fait pour répondre à mes exigences pour les mêmes. J'espère que ceci vous aidera.

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;

}

3
srahul07

Pour une semaine du lundi au dimanche (ISO 8601) (ou, si vous n'y tenez pas), vous pouvez le faire en une seule ligne:

function get_week_of_month($date) {
 return date('W', $date) - date('W', strtotime(date("Y-m-01", $date))) + 1;
}

( La source )

Pour tout le reste, par exemple une semaine du dimanche au samedi, il vous suffit de modifier $ date dans la fonction:

function get_week_of_month($date) {
 $date += 86400; //For weeks starting on Sunday
 return date('W', $date) - date('W', strtotime(date("Y-m-01", $date))) + 1;
}

( Merci à ces gars/filles )

REMARQUE: vous rencontrerez peut-être des problèmes à la fin de l’année (environ 12/31, 1/1, etc.). Lisez plus ici.

2
rinogo

Ce n'est probablement pas une bonne façon de faire mais c'est ma première pensée et je suis vraiment fatiguée.

Mettez toutes vos dates dans un tableau. L'objet de date doit avoir un nom de jour (lundi). Créez une méthode qui recherche dans le tableau et chaque fois que vous frappez un dimanche, vous ajoutez 1 à un compteur hebdomadaire. Une fois que vous avez trouvé la date recherchée, retournez le compteur de semaine. C'est la semaine où tombe le jour de l'année. Pour la semaine du mois, vous devez réinitialiser le compteur de semaine à chaque fois que vous arrivez au dernier jour de chaque mois.

2
Trevor Arjeski

Je pense avoir trouvé une solution élégante

$time = time(); // or whenever
$week_of_the_month = ceil(date('d', $time)/7);
2
Mike Wright

Voici deux doublure:

function getWeekOfMonth(DateTime $date) {
    $firstDayOfMonth = new DateTime($date->format('Y-m-1'));

    return ceil(($firstDayOfMonth->format('N') + $date->format('j') - 1) / 7);
}

Et Les solutions de Wtower ne fonctionnent pas correctement.

2
j4r3k

Je crée cette fonction, du Brésil :) J'espère que c'est utile

function weekofmonth($time) {

    $firstday       = 1;
    $lastday        = date('j',$time);
    $lastdayweek = 6; //Saturday

    $week = 1;
    for ($day=1;$day<=$lastday;$day++) {
        $timetmp = mktime(0, 0, 0, date('n',$time), $day, date('Y',$time));
        if (date('N',$timetmp) == $lastdayweek) {
            $week++;
        }
    }
    if (date('N',$time)==$lastdayweek) {
        $week--;
    }

    return $week;
}

$time = mktime(0, 0, 0, 9, 30, 2014);
echo weekofmonth($time);
1
user3813750

Mes 5 centimes:

/**
* calculate number of weeks in a particular month
*/
function weeksInMonth($month=null,$year=null){

    if( null==($year) ) {
        $year =  date("Y",time());  
    }

    if(null==($month)) {
        $month = date("m",time());
    }

    // find number of days in this month
    $daysInMonths =  date('t',strtotime($year.'-'.$month.'-01'));

    $numOfweeks = ($daysInMonths%7==0?0:1) + intval($daysInMonths/7);

    $monthEndingDay= date('N',strtotime($year.'-'.$month.'-'.$daysInMonths));

    $monthStartDay = date('N',strtotime($year.'-'.$month.'-01'));

    if($monthEndingDay<$monthStartDay){

        $numOfweeks++;

    }

    return $numOfweeks;
}
1
XuDing

Je pensais partager ma fonction aussi. Cela retourne un tableau de semaines. Chaque semaine est un tableau avec semaines jour (0..6) en clé et mois jour (1..31) en valeur.

La fonction suppose que la semaine commence par dimanche.

Prendre plaisir!

function get_weeks($year, $month){

    $days_in_month = date("t", mktime(0, 0, 0, $month, 1, $year));
    $weeks_in_month = 1;
    $weeks = array();

    //loop through month
    for ($day=1; $day<=$days_in_month; $day++) {

        $week_day = date("w", mktime(0, 0, 0, $month, $day, $year));//0..6 starting sunday

        $weeks[$weeks_in_month][$week_day] = $day;

        if ($week_day == 6) {
            $weeks_in_month++;
        }

    }

    return $weeks;

}
1
Krabats

J'ai trouvé un moyen facile de déterminer la semaine du mois d'aujourd'hui et ce serait un petit changement que de le faire fonctionner à une autre date. J'ajoute mes deux cents ici car je pense que mon chemin est beaucoup plus compact que les méthodes énumérées.

$monthstart = date("N",strtotime(date("n/1/Y")));
$date =( date("j")+$monthstart ) /7;
$ddate= floor( $date );
if($ddate != date) {$ddate++;}

et $ ddate contient le numéro de la semaine que vous pourriez modifier comme

function findweek($indate)
{
  $monthstart = date("N",strtotime(date("n/1/Y",strtotime($indate))));
  $date =( date("j",strtotime($indate))+$monthstart ) /7;
  $ddate= floor( $date );
  if($ddate != $date) {$ddate++;}
  return $ddate;
}

et il renverrait quelle semaine du mois la date que vous donnez est . ce qu’elle fait est d’abord trouver le nombre de jours du début de la semaine au premier du mois. ajoute ensuite que le à la date actuelle divise ensuite la nouvelle date par 7, ce qui vous indiquera le nombre de semaines écoulées depuis le début du mois, y compris une décimale pour la partie de la semaine en cours écoulée. ce que je vais faire ensuite, c'est arrondir ce chiffre, puis comparer la version arrondie à l'original si les deux vous correspondent à la fin de la semaine, de sorte que le numéro figure déjà. s'ils ne le font pas, ajoutez simplement un au chiffre arrondi et le tour est joué, vous avez le numéro de la semaine en cours.

1
Kit Ramos

La solution de Srahul07 fonctionne parfaitement ... Si vous respectez le système de la semaine du lundi au dimanche! Ici à Murica, les non-gens d'affaires ont tendance à aller du dimanche au samedi en semaine, donc le 1er mai 2011 est la semaine 1 et le 2 mai 2011 est encore la semaine 1.

Ajouter la logique suivante au bas de sa fonction, juste avant qu'il ne retourne, $ week le convertira en un système Sunday -> Monday:

if (!date('w',strtotime("$year-$month-01")) && date('w',$timestamp))
    $week--;
elseif (date('w',strtotime("$year-$month-01")) && !date('w',$timestamp))
    $week++;
1
Eric Lawler
function get_week_of_month( $timestamp )
{
    $week_of_month = 0; 
    $month = date( 'j', $timestamp );
    $test_month = $month;
    while( $test_month == $month )
    {
        $week_of_month++;
        $timestamp = strtotime( '-1 week', $timestamp );
        $test_month = date( 'j', $timestamp );
    }
    return $week_of_month;
}
0
Algis

J'ai vraiment aimé la réponse de @ michaelc. Cependant, je suis resté bloqué sur quelques points. Il semblait que chaque fois que dimanche arrivait, il y avait un décalage de un. Je pense que cela a à voir avec quel jour de la semaine est le début de la semaine. En tout cas, voici ma légère modification, élargie un peu par souci de lisibilité:

function wom(\DateTime $date) {
    // The week of the year of the current month
    $cw = date('W', $date->getTimestamp());

    // The week of the year of the first of the given month
    $fw = date('W',strtotime(date('Y-m-01',$date->getTimeStamp())));

    // Offset
    $o = 1;

    // If it is a Saturday, offset by two.
    if( date('N',$date->getTimestamp()) == 7 ) {
        $o = 2;
    }

    return $cw -$fw + $o;
}

Donc, si la date est le 9 novembre 2013 ...

$cw = 45
$fw = 44

et avec le décalage de 1, il retourne correctement 2.

Si la date est le 10 novembre 2013, $cw et $fw sont les mêmes qu'auparavant, mais l'offset est 2 et renvoie correctement 3.

0
Abinadi
/**
         * In case of Week we can get the week of year. So whenever we will get the week of the month then we have to
         * subtract the until last month weeks from it will give us the current month week.
         */
        $dateComponents = getdate();

        if($dateComponents['mon'] == 1)
            $weekOfMonth = date('W', strtotime($dateComponents['year'].'-'.$dateComponents['mon'].'-'.$dateComponents['mday']))-1; // We subtract -1 to map it to the array
        else
            $weekOfMonth = date('W', strtotime($dateComponents['year'].'-'.$dateComponents['mon'].'-'.$dateComponents['mday']))-date('W', strtotime($dateComponents['year'].'-'.$dateComponents['mon'].'-01'));
0
Abbas

Python: numéro de la semaine dans un mois

Ceci est un exemple travaillé en Python - devrait être simple à convertir.

0
function getWeekOfMonth(\DateTime $date)
{
    $firstWeekdayOfMonth = new DateTime("first weekday 0 {$date->format('M')} {$date->format('Y')}");
    $offset = $firstWeekdayOfMonth->format('N')-1;
    return intval(($date->format('j') + $offset)/7)+1;
}
0
Elier

J'ai trouvé ceci en ligne: http://kcwebprogrammers.blogspot.de/2009/03/current-week-in-month-php.html

Il a une solution très simple qui semble bien fonctionner pour moi.

$currentWeek = ceiling((date("d") - date("w") - 1) / 7) + 1;

Donc par exemple:

$now = strtotime("today");
$weekOfMonth = ceil((date("d", $now) - date("w", $now) - 1) / 7) + 1;
0
Alex

Court et infaillible:

// Function accepts $date as a string,
// Returns the week number in which the given date falls.
// Assumed week starts on Sunday.
function wom($date) {
  $date = strtotime($date);
  $weeknoofday = date('w', $date);
  $day = date('j', $date);
  $weekofmonth = ceil(($day + (7-($weeknoofday+1))) / 7);
  return $weekofmonth;
}
// Test
foreach (range(1, 31) as $day) {
    $test_date = "2015-01-" . str_pad($day, 2, '0', STR_PAD_LEFT);
    echo "$test_date - ";
    echo wom($test_date) . "\n";
}
0
Kevin Siji

vous pouvez utiliser W dans les nouvelles versions php. http://php.net/manual/en/function.date.php

je l'ai utilisé comme ça:

function getWeek($date) { 
$month_start=strtotime("1 ".date('F Y',$date));
$current_date=strtotime(date('j F Y',$date));

$month_week=date("W",$month_start);
$current_week=date("W",$current_date);
return ($current_week-$month_week);

}//0 is the week of the first.
0
Michael Kent

Si vous souhaitez clairement séparer un mois en 4 semaines, vous pouvez utiliser cette fonction ... 

  • "le premier lundi du mois"
  • "le troisième jeudi du mois" etc.

Et c'est parti

/**
* This Calculates (and returns) the week number within a month, based on date('j') day of month.
* This is useful, if you want to have (for instance) the first Thu in month, regardless of date
* @param $Timestamp
* @return float|int
*/
function getWeekOfMonth($Timestamp)
{
    $DayOfMonth=date('j', $Timestamp); // Day of the month without leading zeros 0-31

    if($DayOfMonth>21) return 4;
    if($DayOfMonth>14) return 3;
    if($DayOfMonth>7) return 2;
    return 1;
}
0
summsel

Après beaucoup d'efforts j'ai trouvé la solution

<?php

function getWeeks($month,$year)
{
    $month = intval($month);        //force month to single integer if '0x'
    $suff = array('st','nd','rd','th','th','th');       //week suffixes
    $end = date('t',mktime(0,0,0,$month,1,$year));      //last date day of month: 28 - 31
    $start = date('w',mktime(0,0,0,$month,1,$year));    //1st day of month: 0 - 6 (Sun - Sat)
    $last = 7 - $start;                     //get last day date (Sat) of first week
    $noweeks = ceil((($end - ($last + 1))/7) + 1);      //total no. weeks in month
    $output = "";                       //initialize string     
    $monthlabel = str_pad($month, 2, '0', STR_PAD_LEFT);
    for($x=1;$x<$noweeks+1;$x++)
    {   
        if($x == 1)
        {
            $startdate = "$year-$monthlabel-01";
            $day = $last - 6;
        }
        else
        {
            $day = $last + 1 + (($x-2)*7);
            $day = str_pad($day, 2, '0', STR_PAD_LEFT);
            $startdate = "$year-$monthlabel-$day";
        }
        if($x == $noweeks)
        {
            $enddate = "$year-$monthlabel-$end";
        }
        else
        {
            $dayend = $day + 6;
            $dayend = str_pad($dayend, 2, '0', STR_PAD_LEFT);
            $enddate = "$year-$monthlabel-$dayend";
        }
        $j=1;
        if($j--)
        {
            $k=getTotalDate($startdate,$enddate);
            $j=1;
        }

    $output .= "Week ".$xyz." week -> Start date=$startdate End date=$enddate <br />";  
    }
    return $output;
}

if(isset($_POST) && !empty($_POST)){
    $month = $_POST['m'];
    $year = $_POST['y']; 
    echo getWeeks($month,$year);
}
?>

<form method="post">
  M:
  <input name="m" value="" />
  Y:
  <input name="y" value="" />
  <input type="submit" value="go" />
</form>

J'utilise cette fonction simple:

function weekNumberInMonth($timestampDate)
{
    $firstDayOfMonth = strtotime(date('01-M-Y 00:00:00', $timestampDate));
    $firstWeekdayOfMonth = date( 'w', $firstDayOfMonth);
    $dayNumberInMonth = date('d', $timestampDate);
    $weekNumberInMonth = ceil(($dayNumberInMonth + $firstWeekdayOfMonth) / 7);
    return $weekNumberInMonth;
}
0
Ali MohammadGhasemi

En utilisant du carbone:

$ date = Carbon :: now (); $ d1 = $ date-> startOfMonth (); $ d2 = $ date-> endOfMonth ();

$ weeks = $ d1-> diffInWeeks ($ d2);

0
carlituxman

si je comprends bien, la question est de savoir comment identifier le nombre de semaines dans un mois d'un jour donné ... Je cherchais une solution similaire. J'ai utilisé quelques idées de réponses ci-dessus pour développer ma propre solution. J'espère que cela peut être utile pour quelqu'un. Si oui, alors UpVote ma réponse.

function week_number_within_month($datenew){

        $year =  date("Y",strtotime($datenew));  
        $month = date("m",strtotime($datenew));

    // find number of days in this month
    $daysInMonths =  date('t',strtotime($year.'-'.$month.'-01'));
    $numOfweeks = ($daysInMonths%7==0?0:1) + intval($daysInMonths/7);
    $monthEndingDay= date('N',strtotime($year.'-'.$month.'-'.$daysInMonths));
    $monthStartDay = date('N',strtotime($year.'-'.$month.'-01'));
    if($monthEndingDay<$monthStartDay){
        $numOfweeks++;
    }
    $date=date('Y/m/d', strtotime($year.'-'. $month.'-01'));
    $week_array=Array();
    for ($i=1; $i<=$numOfweeks; $i++){   /// create an Array of all days of month separated by weeks as a keys
            $max = 7;
            if ($i ==1){ $max = 8 - $monthStartDay;}
            if ($i == $numOfweeks){ $max = $monthEndingDay;}
            for ($r=1; $r<=$max; $r++){

                    $week_array[$i][]=$date;
                    $date = date('Y/m/d',strtotime($date . "+1 days"));
            }
    }
    $new_datenew = date('Y/m/d', strtotime($datenew));
    $week_result='';
        foreach ($week_array as $key => $val){  /// finding what week number of my date from week_array
            foreach ($val as $kr => $value){
            if ($new_datenew == $value){
                $week_result = $key;
            } 
            }
        }
    return $week_result;
}
print week_number_within_month('2016-09-15');
0
Sergiu Costas