Поэтому у меня есть сценарий, который возвращает количество недель в конкретном месяце и году. Как я могу взять конкретный день с этого месяца и определить, является ли он частью недели 1,2,3,4 или 5 в этом месяце?
Самая неприятная вещь, которую я когда-либо пытался получить, – но вот она!
<?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 ?>
Изменить: так много для «одиночной строки» – нужны переменные, чтобы избежать перерасчета с условным. В то время как я был в этом вопросе.
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('Ym-01', $when))); return 1 + ($week < $firstWeekOfMonth ? $week : $week - $firstWeekOfMonth); }
Обратите внимание, что weekOfMonth(strtotime('Oct 31, 2011'));
вернется 6
; некоторые редкие месяцы имеют 6 недель в них, вопреки ожиданиям ОП. Январь 2017 – это еще один месяц с 6 неделями ISO – воскресенье 1-го числа приходится на прошлогоднюю неделю, так как недели ИСО начинаются в понедельник.
Для starshine531 , чтобы вернуть индексированную неделю месяца, измените значение return 1 +
чтобы return 0 +
или return (int)
.
Для Юстина Стайтона в течение недель, начинающихся в воскресенье вместо понедельника, я буду использовать 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('Ym-01', $when))); return 1 + ($week < $firstWeekOfMonth ? $week : $week - $firstWeekOfMonth); }
Для этой версии 2017-04-30 сейчас на 6-й неделе, а 2017-01-31 – на 5-й неделе.
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; }
Привет всем, я изо всех сил пытался целый день попытаться понять этот код, я, наконец, понял это, поэтому я думал, что поделюсь им со всеми вами.
все, что вам нужно сделать, это установить временную метку в функцию, и она вернет вам номер недели.
благодаря
проблема с этим методом. если дата перехода (скажем, 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; }
Это решение основано на математическом решении 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; }
Просто скопируйте и пропустите код и пройдите месяц и год.
например, месяц = 04 год = 2013 год.
Это именно то, что вам нужно.
$mm= $_REQUEST['month']; $yy= $_REQUEST['year']; $startdate=date($yy."-".$mm."-01") ; $current_date=date('Ym-t'); $ld= cal_days_in_month(CAL_GREGORIAN, $mm, $yy); $lastday=$yy.'-'.$mm.'-'.$ld; $start_date = date('Ym-d', strtotime($startdate)); $end_date = date('Ym-d', strtotime($lastday)); $end_date1 = date('Ym-d', strtotime($lastday." + 6 days")); $count_week=0; $week_array = array(); for($date = $start_date; $date <= $end_date1; $date = date('Ym-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("Ymd", strtotime("{$year}-W{$week}+1")); if($from < $start_date) $from = $start_date; $to = date("Ymd", 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
Это фрагмент, который я сделал для выполнения моих требований для этого же. Надеюсь, что это поможет вам.
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;
}
Это, вероятно, не очень хороший способ сделать это, но это моя первая мысль, и я действительно устал.
Поместите все свои даты в массив. Объект date должен иметь имя дня (понедельник). Создайте метод поиска массива, и когда вы нажмете воскресенье, вы добавите счетчик 1 в неделю. Как только вы найдете дату, которую вы ищете, возвратите счетчик недели. Это неделя, когда день выпадает на год. За неделю в месяц вам нужно сбросить счетчик недели каждый раз, когда вы добираетесь до последнего дня в каждом месяце.
Думаю, я нашел элегантное решение
$time = time(); // or whenever $week_of_the_month = ceil(date('d', $time)/7);
Вот два лайнера:
function getWeekOfMonth(DateTime $date) { $firstDayOfMonth = new DateTime($date->format('Ym-1')); return ceil(($firstDayOfMonth->format('N') + $date->format('j') - 1) / 7); }
И решения Wtower не работают на 100%.
Для недели с понедельника по воскресенье (ISO 8601) (или, если вам просто все равно), вы можете сделать это в одной строке:
function get_week_of_month($date) { return date('W', $date) - date('W', strtotime(date("Ym-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("Ym-01", $date))) + 1; }
( Спасибо этим парням / галям )
ПРИМЕЧАНИЕ. Вы можете столкнуться с некоторыми проблемами в конце года (например, около 12/31, 1/1 и т. Д.). Подробнее читайте здесь.
Думал, что я поделился своей функцией. Это возвращает несколько недель. Каждая неделя представляет собой массив с недельным днем (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; }
Мои 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; }
Я создаю эту функцию из Бразилии 🙂 Надеюсь, это полезно
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);
Я нашел простой способ определить, какая неделя месяца в этом месяце, и было бы небольшим изменением, чтобы он работал в любую другую дату. Я добавляю свои два цента здесь, так как, по-моему, мой путь намного более компактен, чем перечисленные методы.
$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, и это даст вам, сколько недель прошло с начала месяца, включая десятичное место для той части прошедшей недели. поэтому то, что я делаю дальше, округляет это число, а затем сравнивает округленную версию с оригиналом, если они совпадают с вашими в конце недели, так что они уже находятся в номере. если они этого не делают, просто добавьте их к округленному номеру и вуале, у вас есть номер текущей недели.
Python: число недель в месяц
Это обработанный пример в Python – должен быть простым для преобразования.
Решение 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++;
Кажется, что это работает для всех случаев, месяцев, начиная с воскресенья, января 2011, 2012 и 2013 годов, а также всех других случайных дат, которые я подключил. Спасибо за эту функцию, С. Рахул.
К сожалению, после всей моей работы по запуску этой функции, я узнаю, что мои пользователи используют более смешную систему, в которой понятие «недели» слишком сложное, поэтому они просто подсчитывают количество дней в месяце и игнорируют все «неделя», в которой мы находимся. Единая система подсчета количества пятниц и т. д. уже произошла в этом месяце, это единственное решение, которое я мог бы придумать, потому что это их логика. T_T
После многого, я нашел решение
<?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>
Мне очень понравился ответ @ 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('Ym-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.
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; }
Я нашел это онлайн: 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;
вы можете использовать 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.
Короткий и надежный:
// 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"; }
Я использую эту простую функцию:
function weekNumberInMonth($timestampDate) { $firstDayOfMonth = strtotime(date('01-MY 00:00:00', $timestampDate)); $firstWeekdayOfMonth = date( 'w', $firstDayOfMonth); $dayNumberInMonth = date('d', $timestampDate); $weekNumberInMonth = ceil(($dayNumberInMonth + $firstWeekdayOfMonth) / 7); return $weekNumberInMonth; }
если я правильно понял, вопрос заключается в том, как определить, какое количество недель в течение месяца определенного дня … Я искал аналогичное решение. Я использовал некоторые идеи из вышеприведенных ответов, чтобы разработать собственное решение. Надеюсь, это может быть полезно для кого-то. Если да, то UpVote мой ответ.
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');
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; }
/** * 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'));
Использование углерода:
$ date = Carbon :: now (); $ d1 = $ date-> startOfMonth (); $ d2 = $ date-> endOfMonth ();
$ weeks = $ d1-> diffInWeeks ($ d2);