计算一周的周数

时间:2008-10-09 08:42:11

标签: php date

给出一周的数字,例如date -u +%W,您如何计算从周一开始的那一周的天数?

第40周的rfc-3339输出示例:

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

14 个答案:

答案 0 :(得分:59)

<强> 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中,改编自this post上的PHP date manual page

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
)

答案 1 :(得分:7)

如果您有Zend Framework,可以使用Zend_Date类来执行此操作:

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 '</pre>';

答案 2 :(得分:6)

由于这个问题和接受的答案已经发布,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));

这具有照顾闰年等的额外优势。

See it working。包括困难的第1周和第53周。

答案 3 :(得分:4)

此计算在很大程度上取决于您居住的地方。例如,在欧洲,我们以星期一开始本周,而美国星期日是本周的第一天。在英国,第1周是1月1日,其他国家在本周的第一周开始第1周。

您可以在http://en.wikipedia.org/wiki/Week#Week_number

找到更多一般信息

答案 4 :(得分:2)

此函数将给出找到$ date的星期几的时间戳。如果没有给出$ date,则假定为“now”。如果您更喜欢可读日期到时间戳,请将日期格式传递给第二个参数。如果你没有在周一开始你的一周(幸运),那么在另一天通过第三个参数。

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
)

答案 5 :(得分:2)

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

//==============================//

答案 6 :(得分:1)

另一个代码呵呵:

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

答案 7 :(得分:0)

我发现此解决方案存在问题。 我不得不将周数填零,否则它就会破裂。

我的解决方案现在看起来像这样:

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

答案 8 :(得分:0)

对于那些寻找周数的人(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]))); }

答案 9 :(得分:0)

我有同样的问题,只使用strftime而不是date作为我的起点,即使用%W从strftime派生周数我想知道那周的日期范围 - 周一到周日(或实际上是任何开始日)。对几个类似帖子的回顾,特别是尝试了上述几种方法,并没有让我得到我想要的解决方案。当然,我可能误解了一些东西,但我无法得到我想要的东西。

我想分享我的解决方案。

我的第一个想法是,鉴于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年,这是第一年的1/1/2018 =周一。到目前为止似乎提供了正确的日期范围。

所以我希望这会有所帮助。

此致

答案 10 :(得分:0)

另一种解决方案:

//$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

答案 11 :(得分:0)

$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 '</pre>';

用作php中的date()对象 date php

答案 12 :(得分:0)

基于周数和天数的时间段

一些国家(如斯堪的纳维亚国家和德国)使用周数作为预订假期、会议等的实用方式。此功能可以根据周数开始日期和以天为单位的周期长度发送有关该周期的短信。< /p>

function MakePeriod($year,$Week,$StartDay,$NumberOfDays, $lan='DK'){
    //Please note that start dates in january of week 53 must be entered as "the year before"
    switch($lan){
    case "NO":
        $WeekDays=['mandag','tirsdag','onsdag','torsdag','fredag','lørdag','søndag'];
        $the=" den ";
        $weekName="Uke ";
        $dateformat="j/n Y";
    break;      
    case "DK":
        $WeekDays=['mandag','tirsdag','onsdag','torsdag','fredag','lørdag','søndag'];
        $the=" den ";
        $weekName="Uge ";
        $dateformat="j/n Y";
    break;
    case "SV":
        $WeekDays=['måndag','tisdag','onsdag','torsdag','fredag','lördag','söndag'];
        $the=" den ";
        $weekName="Vecka ";
        $dateformat="j/n Y";
    break;
    case "GE":
        $WeekDays=['Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag','Sonntag'];
        $the=" die ";
        $weekName="Woche ";
        $dateformat="j/n Y";
    break;
    case "EN":
    case "US":  
        $WeekDays=['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'];
        $the=" the ";
        $weekName="Week ";
        $dateformat="n/j/Y";
    break;  
    }   
    $EndDay= (($StartDay-1+$NumberOfDays) % 7)+1;
    $ExtraDays= $NumberOfDays % 7;
    $FirstWeek=$Week;
    $LastWeek=$Week;    
    $NumberOfWeeks=floor($NumberOfDays / 7) ;
    $LastWeek=$Week+$NumberOfWeeks;

    if($StartDay+$ExtraDays>7){
        $LastWeek++;
    }       

    if($FirstWeek<10) $FirstWeek='0'.$FirstWeek;
    if($LastWeek<10) $LastWeek='0'.$LastWeek;

    
    $date1 = date( $dateformat, strtotime($year."W".$FirstWeek.$StartDay) ); // First day of week

    $date2 = date( $dateformat, strtotime($year."W".$LastWeek.$EndDay) ); // Last day of week

    if($LastWeek>53){
        $LastWeek=$LastWeek-53;
        $year++;
        if($LastWeek<10) $LastWeek='0'.$LastWeek;
        $date2 = date( $dateformat, strtotime($year."W".$LastWeek.$EndDay) );
    }
    $EndDayName=$WeekDays[$EndDay-1];
    $StartDayName=$WeekDays[$StartDay-1];
    $retval= " $weekName $Week $StartDayName  $the $date1 - $EndDayName $the $date2 ";
    return $retval;     
    
}

测试:

$Year=2021;
$Week=22;   
$StartDay=4;    
$NumberOfDays=3;
$Period=MakePeriod($Year,$Week,$StartDay,$NumberOfDays,"DK");
echo $Period;

Uge 22 torsdag den 2021 年 3 月 6 日 - søndag den 2021 年 6 月 6 日

答案 13 :(得分:-1)

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