Расчет дней недели по номеру недели - 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 ]

59 голосов
/ 09 октября 2008

PHP

$week_number = 40;
$year = 2008;
for($day=1; $day<=7; $day++)
{
    echo date('m/d/Y', strtotime($year."W".$week_number.$day))."\n";
}


Ниже был пост, потому что я был идиотом, который не прочитал вопрос должным образом, но получит даты недели, начиная с понедельника, с учетом даты, а не номера недели.

В PHP , адаптировано из этого поста на странице руководства по дате PHP :

function week_from_monday($date) {
    // Assuming $date is in format DD-MM-YYYY
    list($day, $month, $year) = explode("-", $_REQUEST["date"]);

    // Get the weekday of the given date
    $wkday = date('l',mktime('0','0','0', $month, $day, $year));

    switch($wkday) {
        case 'Monday': $numDaysToMon = 0; break;
        case 'Tuesday': $numDaysToMon = 1; break;
        case 'Wednesday': $numDaysToMon = 2; break;
        case 'Thursday': $numDaysToMon = 3; break;
        case 'Friday': $numDaysToMon = 4; break;
        case 'Saturday': $numDaysToMon = 5; break;
        case 'Sunday': $numDaysToMon = 6; break;   
    }

    // Timestamp of the monday for that week
    $monday = mktime('0','0','0', $month, $day-$numDaysToMon, $year);

    $seconds_in_a_day = 86400;

    // Get date for 7 days from Monday (inclusive)
    for($i=0; $i<7; $i++)
    {
        $dates[$i] = date('Y-m-d',$monday+($seconds_in_a_day*$i));
    }

    return $dates;
}

Вывод из week_from_monday('07-10-2008') дает:

Array
(
    [0] => 2008-10-06
    [1] => 2008-10-07
    [2] => 2008-10-08
    [3] => 2008-10-09
    [4] => 2008-10-10
    [5] => 2008-10-11
    [6] => 2008-10-12
)
7 голосов
/ 10 октября 2008

Если у вас есть Zend Framework, вы можете использовать класс Zend_Date для этого:

<code>require_once 'Zend/Date.php';

$date = new Zend_Date();
$date->setYear(2008)
     ->setWeek(40)
     ->setWeekDay(1);

$weekDates = array();

for ($day = 1; $day <= 7; $day++) {
    if ($day == 1) {
        // we're already at day 1
    }
    else {
        // get the next day in the week
        $date->addDay(1);
    }

    $weekDates[] = date('Y-m-d', $date->getTimestamp());
}

echo '<pre>';
print_r($weekDates);
echo '
';
6 голосов
/ 12 июня 2013

Поскольку этот вопрос и принятый ответ были опубликованы, классы DateTime делают это намного проще:

function daysInWeek($weekNum)
{
    $result = array();
    $datetime = new DateTime('00:00:00');
    $datetime->setISODate((int)$datetime->format('o'), $weekNum, 1);
    $interval = new DateInterval('P1D');
    $week = new DatePeriod($datetime, $interval, 6);

    foreach($week as $day){
        $result[] = $day->format('D d m Y H:i:s');
    }
    return $result;
}

var_dump(daysInWeek(24));

Это дает дополнительное преимущество заботы о високосных годах и т. Д.

Смотри, как работает . Включая трудные недели 1 и 53.

4 голосов
/ 09 октября 2008

Этот расчет сильно зависит от того, где вы живете. Например, в Европе мы начинаем неделю с понедельника, в США воскресенье - первый день недели. В Великобритании 1-я неделя - 1 января, в других странах первая неделя начинается с недели с первым четвергом года.

Более общую информацию можно найти на http://en.wikipedia.org/wiki/Week#Week_number

2 голосов
/ 29 декабря 2009
$week_number = 40;
$year = 2008;

for($day=1; $day<=7; $day++)
{
    echo date('m/d/Y', strtotime($year."W".$week_number.$day))."\n";
}

Это не удастся, если $week_number меньше 10.

//============Try this================//

$week_number = 40;
$year = 2008;

if($week_number < 10){
   $week_number = "0".$week_number;
}

for($day=1; $day<=7; $day++)
{
    echo date('m/d/Y', strtotime($year."W".$week_number.$day))."\n";
}

//==============================//
2 голосов
/ 11 февраля 2009

Эта функция выдаёт временные метки дней недели, в которые найдена $ date. Если $ date не указан, он предполагает «сейчас». Если вы предпочитаете читаемые даты меткам времени, передайте формат даты во второй параметр. Если вы не начинаете свою неделю в понедельник (повезло), перейдите в другой день для третьего параметра.

function week_dates($date = null, $format = null, $start = 'monday') {
  // is date given? if not, use current time...
  if(is_null($date)) $date = 'now';

  // get the timestamp of the day that started $date's week...
  $weekstart = strtotime('last '.$start, strtotime($date));

  // add 86400 to the timestamp for each day that follows it...
  for($i = 0; $i < 7; $i++) {
    $day = $weekstart + (86400 * $i);
    if(is_null($format)) $dates[$i] = $day;
    else $dates[$i] = date($format, $day);
  }

  return $dates;
}

Так что week_dates () должно возвращать что-то вроде ...

Array ( 
  [0] => 1234155600 
  [1] => 1234242000 
  [2] => 1234328400 
  [3] => 1234414800 
  [4] => 1234501200
  [5] => 1234587600
  [6] => 1234674000
)
1 голос
/ 06 января 2016

Другой код хе-хе:

public function getAllowedDays($year, $week) {
    $weekDaysArray = array();
    $dto = new \DateTime();
    $dto->setISODate($year, $week);

    for($i = 0; $i < 7; $i++) {
        array_push($weekDaysArray, $dto->format('Y-m-d'));
        $dto->modify("+1 days");
    }

    return $weekDaysArray;
}
0 голосов
/ 16 ноября 2016
<code>$year      = 2016; //enter the year
$wk_number = 46;   //enter the weak nr

$start = new DateTime($year.'-01-01 00:00:00');
$end   = new DateTime($year.'-12-31 00:00:00');

$start_date = $start->format('Y-m-d H:i:s');

$output[0]= $start;    
$end   = $end->format('U');    
$x = 1;

//create array full of data objects
for($i=0;;$i++){
    if($i == intval(date('z',$end)) || $i === 365){
        break;
    }
    $a = new DateTime($start_date);
    $b = $a->modify('+1 day');
    $output[$x]= $a;        
    $start_date = $b->format('Y-m-d H:i:s');
    $x++;
}    

//create a object to use
for($i=0;$i<count($output);$i++){
    if(intval ($output[$i]->format('W')) === $wk_number){
        $output_[$output[$i]->format('N')]        = $output[$i];
    }
}

$dayNumberOfWeek = 1; //enter the desired day in 1 = Mon -> 7 = Sun

echo '<pre>';
print_r($output_[$dayNumberOfWeek]->format('Y-m-d'));
echo '
';

использовать в качестве объекта date () из php дата php

0 голосов
/ 19 февраля 2014
    <?php
    $iWeeksAgo = 5;// need weeks ago
    $sWeekDayStartOn = 0;// 0 - Sunday, 1 - Monday, 2 - Tuesday
    $aWeeksDetails = getWeekDetails($iWeeksAgo, $sWeekDayStartOn);

    print_r($aWeeksDetails);
    die('end of line of getWeekDetails ');

    function getWeekDetails($iWeeksAgo, $sWeekDayStartOn){
        $date = new DateTime();
        $sCurrentDate = $date->format('W, Y-m-d, w');
        #echo 'Current Date (Week of the year, YYYY-MM-DD, day of week ): ' . $sCurrentDate . "\n";

        $iWeekOfTheYear = $date->format('W');// Week of the Year i.e. 19-Feb-2014 = 08
        $iDayOfWeek = $date->format('w');// day of week for the current month i.e. 19-Feb-2014 = 4
        $iDayOfMonth = $date->format('d'); // date of the month i.e. 19-Feb-2014 = 19

        $iNoDaysAdd = 6;// number of days adding to get last date of the week i.e. 19-Feb-2014  + 6 days = 25-Feb-2014

        $date->sub(new DateInterval("P{$iDayOfWeek}D"));// getting start date of the week
        $sStartDateOfWeek = $date->format('Y-m-d');// getting start date of the week

        $date->add(new DateInterval("P{$iNoDaysAdd}D"));// getting end date of the week
        $sEndDateOfWeek = $date->format('Y-m-d');// getting end date of the week

        $iWeekOfTheYearWeek = (string) $date->format('YW');//week of the year
        $iWeekOfTheYearWeekWithPeriod = (string) $date->format('Y-W');//week of the year with year

        //To check uncomment
        #echo "Start Date / End Date of Current week($iWeekOfTheYearWeek), week with - ($iWeekOfTheYearWeekWithPeriod) : " . $sStartDateOfWeek . ',' . $sEndDateOfWeek . "\n";

        $iDaysAgo = ($iWeeksAgo*7) + $iNoDaysAdd + $sWeekDayStartOn;// getting 4 weeks ago i.e. no. of days to substract

        $date->sub(new DateInterval("P{$iDaysAgo}D"));// getting 4 weeks ago i.e. no. of days to substract
        $sStartDateOfWeekAgo = $date->format('Y-m-d');// getting 4 weeks ago start date i.e. 19-Jan-2014

        $date->add(new DateInterval("P{$iNoDaysAdd}D")); // getting 4 weeks ago end date i.e. 25-Jan-2014
        $sEndDateOfWeekAgo = $date->format('Y-m-d');// getting 4 weeks ago start date i.e. 25-Jan-2014

        $iProccessedWeekAgoOfTheYear = (string) $date->format('YW');//ago week of the year
        $iProccessedWeekOfTheYearWeekAgo = (string) $date->format('YW');//ago week of the year with year
        $iProccessedWeekOfTheYearWeekWithPeriodAgo = (string) $date->format('Y-W');//ago week of the year with year

        //To check uncomment
        #echo "Start Date / End Date of week($iProccessedWeekOfTheYearWeekAgo), week with - ($iProccessedWeekOfTheYearWeekWithPeriodAgo) ago: " . $sStartDateOfWeekAgo . ',' . $sEndDateOfWeekAgo . "\n";

        $aWeeksDetails = array ('weeksago' => $iWeeksAgo, 'currentweek' => $iWeekOfTheYear, 'currentdate' => $sCurrentDate, 'startdateofcurrentweek' => $sStartDateOfWeek,  'enddateofcurrentweek' => $sEndDateOfWeek,
                                'weekagoyearweek' => $iProccessedWeekAgoOfTheYear, 'startdateofagoweek' => $sStartDateOfWeekAgo,  'enddateofagoweek' => $sEndDateOfWeekAgo);

        return $aWeeksDetails;
    }
?> 
0 голосов
/ 31 января 2014

Другое решение:

//$date Date in week
//$start Week start (out)
//$end Week end (out)

function week_bounds($date, &$start, &$end) {
    $date = strtotime($date);
    $start = $date;
    while( date('w', $start)>1 ) {
        $start -= 86400;
    }
    $end = date('Y-m-d', $start + (6*86400) );
    $start = date('Y-m-d', $start);
}

Пример:

week_bounds("2014/02/10", $start, $end);
echo $start."<br>".$end;

Из:

2014-02-10
2014-02-16
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...