У меня был тот же вопрос, только с использованием strftime вместо даты в качестве отправной точки, то есть, получив номер недели из strftime с использованием% W, я хотел узнать диапазон дат для этой недели - с понедельника по воскресенье (или, действительно, любой начальный день). Обзор нескольких похожих постов и, в частности, попытка парочки вышеперечисленных подходов не привели меня к решению, которое я хотел. Конечно, я мог что-то неправильно понять, но я не мог получить то, что хотел.
Поэтому я хотел бы поделиться своим решением.
Моей первой мыслью было, что с учетом описания strftime% W это:
номер недели текущего года, начиная с первого понедельника как
первый день первой недели
Если бы я установил, какой первый понедельник каждого года, я мог бы вычислить массив диапазонов дат с индексом, равным значению% W. После этого я мог вызвать функцию, используя strftime.
Итак, вот так:
Функция:
<?php
/*
* function to establish scope of week given a week of the year value returned from strftime %W
*/
// note strftime %W reports 1/1/YYYY as wk 00 unless 1/1/YYYY is a monday when it reports wk 01
// note strtotime Monday [last, this, next] week - runs sun - sat
function date_Range_For_Week($W,$Y){
// where $W = %W returned from strftime
// $Y = %Y returned from strftime
// establish 1st day of 1/1/YYYY
$first_Day_Of_Year = mktime(0,0,0,1,1,$Y);
// establish the first monday of year after 1/1/YYYY
$first_Monday_Of_Year = strtotime("Monday this week",(mktime(0,0,0,1,1,$Y)));
// Check for week 00 advance first monday if found
// We could use strtotime "Monday next week" or add 604800 seconds to find next monday
// I have decided to avoid any potential strtotime overhead and do the arthimetic
if (strftime("%W",$first_Monday_Of_Year) != "01"){
$first_Monday_Of_Year += (60 * 60 * 24 * 7);
}
// create array to ranges for the year. Note 52 wks is the norm but it is possible to have 54 weeks
// in a given yr therefore allow for this in array index
$week_Start = array();
$week_End = array();
for($i=0;$i<=53;$i++){
if ($i == 0){
if ($first_Day_Of_Year != $first_Monday_Of_Year){
$week_Start[$i] = $first_Day_Of_Year;
$week_End[$i] = $first_Monday_Of_Year - (60 * 60 * 24 * 1);
} else {
// %W returns no week 00
$week_Start[$i] = 0;
$week_End[$i] = 0;
}
$current_Monday = $first_Monday_Of_Year;
} else {
$week_Start[$i] = $current_Monday;
$week_End[$i] = $current_Monday + (60 * 60 * 24 * 6);
// find next monday
$current_Monday += (60 * 60 * 24 * 7);
// test for end of year
if (strftime("%W",$current_Monday) == "01"){ $i = 999; };
}
};
$result = array("start" => strftime("%a on %d, %b, %Y", $week_Start[$W]), "end" => strftime("%a on %d, %b, %Y", $week_End[$W]));
return $result;
}
?>
Пример:
// usage example
//assume we wish to find the date range of a week for a given date July 12th 2011
$Y = strftime("%Y",mktime(0,0,0,7,12,2011));
$W = strftime("%W",mktime(0,0,0,7,12,2011));
// use dynamic array variable to check if we have range if so get result if not run function
$date_Range = date_Range . "$Y";
isset(${$date_Range}) ? null : ${$date_Range} = date_Range_For_Week($W, $Y);
echo "Date sought: " . strftime(" was %a on %b %d, %Y, %X time zone: %Z",mktime(0,0,0,7,12,2011)) . "<br/>";
echo "start of week " . $W . " is " . ${$date_Range}["start"] . "<br/>";
echo "end of week " . $W . " is " . ${$date_Range}["end"];
Выход:
> Date sought: was Tue on Jul 12, 2011, 00:00:00 time zone: GMT Daylight
> Time start of week 28 is Mon on 11, Jul, 2011 end of week 28 is Sun on
> 17, Jul, 2011
Я проверял это в течение нескольких лет, включая 2018 год, который наступит в следующем году, когда 01.01.08 = понедельник. До сих пор, кажется, поставил правильный диапазон дат.
Так что я надеюсь, что это поможет.
Привет