Расчет дней недели по номеру недели - PullRequest
27 голосов
/ 09 октября 2008

Номер недели, например, date -u +%W, как вы рассчитываете дни этой недели, начиная с понедельника?

Пример вывода rfc-3339 за неделю 40:

2008-10-06
2008-10-07
2008-10-08
2008-10-09
2008-10-10
2008-10-11
2008-10-12

Ответы [ 13 ]

0 голосов
/ 03 сентября 2012

У меня был тот же вопрос, только с использованием 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 = понедельник. До сих пор, кажется, поставил правильный диапазон дат.

Так что я надеюсь, что это поможет.

Привет

0 голосов
/ 26 июля 2009

Для тех, кто ищет дни недели с указанным номером недели (1-52) Начиная с воскресенья , вот моя небольшая работа вокруг. Принимает во внимание, что неделя находится в правильном диапазоне, и дополняет значения 1-9, чтобы все это работало.

$week = 2; $year = 2009;

$week = (($week >= 1) AND ($week <= 52))?($week-1):(1);

$dayrange  = array(7,1,2,3,4,5,6);

for($count=0; $count<=6; $count++) {
    $week = ($count == 1)?($week + 1): ($week);
    $week = str_pad($week,2,'0',STR_PAD_LEFT);
    echo date('d m Y', strtotime($year."W".$week.($dayrange[$count]))); }
0 голосов
/ 12 марта 2009

Я нашел проблему с этим решением. Я должен был обнулить номер недели, иначе он ломался.

Мое решение выглядит так:

$week_number = 40;
$year = 2008;
for($day=1; $day<=7; $day++)
{
    echo date('m/d/Y', strtotime($year."W".str_pad($week_number,2,'0',STR_PAD_LEFT).$day))."\n";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...