Подтвердить что ты не робот

PHP получает номер недели за месяц

Итак, у меня есть script, который возвращает количество недель в конкретном месяце и году. Как я могу взять конкретный день с этого месяца и определить, является ли он частью недели 1,2,3,4 или 5 в этом месяце?

4b9b3361

Ответ 1

Самая неприятная вещь, которую я когда-либо пытался получить, - но вот она!

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

Ответ 2

Изменить: так много для "одиночной строки" - необходимые переменные, чтобы избежать перерасчета с условным. В то время как я был в этом вопросе, меняет аргумент по умолчанию.

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

Обратите внимание, что weekOfMonth(strtotime('Oct 31, 2011')); вернет 6; некоторые редкие месяцы имеют 6 недель в них, вопреки ожиданиям ОП. Январь 2017 - еще один месяц с 6 неделями ISO - воскресенье 1-го числа приходится на прошлую неделю, так как недели ISO начинаются в понедельник.

Для starshine531, чтобы вернуть индексированную неделю месяца 0, измените return 1 + на return 0 + или return (int).

Для Justin Stayton, начиная с воскресенья вместо понедельника, я бы использовал strftime('%U' вместо date('W' следующим образом:

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

Для этой версии 2017-04-30 сейчас находится на 6-й неделе, а 2017-01-31 - на 5-й неделе.

Ответ 3

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

Привет всем, я изо всех сил пытался целый день пытаться понять этот код, я, наконец, понял это, поэтому я думал, что поделюсь им со всеми вами.

все, что вам нужно сделать, это поместить отметку времени в функцию, и она вернет вам номер недели.

спасибо

Ответ 4

существует проблема с этим методом. если дата перехода (скажем, 2012/01/01, которая является воскресенью), а день "$ rollover" - "воскресенье", тогда эта функция вернется 2. где ее действительно 1-я неделя. Я думаю, что исправил его в следующей функции. добавьте комментарии, чтобы сделать их лучше.

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

Ответ 5

Это решение основано на математическом решении sberry, но вместо этого используется PHP DateTime.

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

Ответ 6

Просто скопируйте и пропустите код и укажите месяц и год.

год = 04 год = 2013.

Это именно то, что вам нужно.

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

ВЫВОД:

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

Ответ 7

Это фрагмент, который я сделал для выполнения моих требований для этого. Надеюсь, это поможет вам.

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

}

Ответ 8

Это, вероятно, не очень хороший способ сделать это, но это моя первая мысль, и я действительно устал.

Поместите все свои даты в массив. Объект date должен иметь имя дня (понедельник). Создайте метод поиска массива, и когда вы нажмете воскресенье, вы добавите счетчик 1 в неделю. Как только вы найдете дату, которую вы ищете, возвратите счетчик недели. Это неделя, когда день выпадает на год. За неделю в месяц вы должны reset счетчик недели каждый раз, когда вы добираетесь до последнего дня в каждом месяце.

Ответ 9

В течение недели с понедельника по воскресенье (ISO 8601) (или, если вам просто все равно), вы можете сделать это в одной строке:

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

(Источник)

Для чего-либо еще (например, в воскресенье-субботу) вам просто нужно настроить $date внутри функции:

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

(Спасибо этим парням /gals)

ПРИМЕЧАНИЕ. Вы можете столкнуться с некоторыми проблемами в конце года (например, около 12/31, 1/1 и т.д.). Подробнее здесь.

Ответ 10

Думаю, я нашел элегантное решение

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

Ответ 11

Вот два лайнера:

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

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

И Решения Wtower не работают на 100%.

Ответ 12

Решение Srahul07 прекрасно работает... Если вы соблюдаете систему понедельник-воскресенье недели! Здесь, в "мурика", не-бизнесмены, как правило, ходят по воскресеньям-субботам на неделю, поэтому 1 мая 2011 года - 1 неделя и 2 мая 2011 года - еще 1 неделя.

Добавление следующей логики в нижнюю часть его функции, прямо перед тем, как она вернет $ week, преобразует ее в систему Sunday → Monday:

if (!date('w',strtotime("$year-$month-01")) && date('w',$timestamp))
    $week--;
elseif (date('w',strtotime("$year-$month-01")) && !date('w',$timestamp))
    $week++;

Ответ 13

Я нашел простой способ определить, какая именно неделя месяца в настоящее время, и было бы небольшим изменением, чтобы он работал в любую другую дату. Я добавляю свои два цента здесь, поскольку, по-моему, мой способ намного более компактен, чем перечисленные методы.

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

и $ddate содержит номер недели, который вы могли бы изменить таким образом

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

и он вернет в какой неделе месяца любую дату, которую вы дадите. то, что он делает, это сначала найти количество дней с начала недели до первого месяца. затем добавляет, что на текущую дату затем делит новую дату на 7, и это даст вам, сколько недель прошло с начала месяца, включая десятичное место для той части прошедшей недели. поэтому то, что я делаю дальше, округляет это число, а затем сравнивает округленную версию с оригиналом, если они совпадают с вашими в конце недели, так что они уже в номере. если они этого не делают, просто добавьте их к округленному номеру и вуале, у вас есть номер текущей недели.

Ответ 14

Думаю, что я поделился бы своей функцией. Это возвращает несколько недель. Каждая неделя представляет собой массив с недельным днем ​​(0..6) как ключ и месяц (1..31) в качестве значения.

Функция предполагает, что неделя начинается с воскресенья.

Наслаждайтесь!

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;

}

Ответ 15

Мои 5 центов:

/**
* 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;
}

Ответ 16

Я создаю эту функцию из Бразилии:) Надеюсь, это полезно

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

Ответ 18

После большого количества efoort я нашел решение

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

Ответ 19

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

Ответ 20

Мне очень понравился ответ @michaelc. Тем не менее, я застрял в нескольких точках. Казалось, что каждый раз, когда воскресенье катится, было смещение одного. Я думаю, что это связано с тем, какой день недели - начало недели. В любом случае, вот мое небольшое изменение к нему, немного расширенное для удобочитаемости:

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

Итак, если дата 9 ноября 2013 года...

$cw = 45
$fw = 44

и со смещением 1, он правильно возвращает 2.

Если дата 10 ноября 2013 года, $cw и $fw такие же, как раньше, но смещение равно 2, и оно правильно возвращает 3.

Ответ 21

Я нашел это онлайн: http://kcwebprogrammers.blogspot.de/2009/03/current-week-in-month-php.html

У него очень простое решение, которое, похоже, отлично работает для меня.

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

Итак, например:

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

Ответ 22

вы можете использовать W в новых версиях php. http://php.net/manual/en/function.date.php

Я использовал его так:

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.

Ответ 23

Короткий и надежный:

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

Ответ 24

Я использую эту простую функцию:

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

Ответ 25

Если я правильно понял, вопрос в том, как определить, какое количество недель в течение месяца определенного дня... Я искал аналогичное решение. Я использовал некоторые идеи из вышеприведенных ответов, чтобы разработать собственное решение. Надеюсь, это может быть полезно для кого-то. Если "Да", то "Направьте мой ответ".

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

Ответ 26

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

Ответ 27

/**
         * 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'));

Ответ 28

Использование углерода:

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

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

Ответ 29

Если вы четко хотите разделить месяц на 4 недели, вы можете использовать эту функцию. Это полезно, если вы хотите

  • "первый месяц месяца"
  • "третий четверг месяца" и т.д.

Вот так

/**
* 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;
}

Ответ 30

Из углерода:

return (int) ceil((new Datetime())->format('d') / 7);

Как можно проще :)