web-dev-qa-db-fra.com

Calcul des jours de la semaine à partir d'un numéro de semaine

Étant donné un numéro de semaine, par exemple date -u +%W, comment calculez-vous les jours de cette semaine à partir du lundi?

Exemple de sortie RFC-3339 pour la semaine 40:

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

PHP

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


Le message ci-dessous était dû au fait que j'étais un idiot qui ne lisait pas la question correctement, mais obtiendrais les dates dans une semaine à partir du lundi, compte tenu de la date et non du numéro de la semaine.

Dans PHP, adapté de ce message sur la page de manuel de PHP date :

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

La sortie de week_from_monday('07-10-2008') donne:

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
)
59
ConroyP

Si vous avez Zend Framework, vous pouvez utiliser la classe Zend_Date pour faire ceci:

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>';
7
Shane

Depuis que cette question et la réponse acceptée ont été postées, les classes DateTime simplifient beaucoup cette opération: -

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

Cela a l'avantage supplémentaire de prendre soin des années bissextiles, etc.

Voir le travail . Y compris les semaines difficiles 1 et 53.

6
vascowhite

Ce calcul varie grandement selon l'endroit où vous vivez. Par exemple, en Europe, nous commençons la semaine avec un lundi, aux États-Unis, le dimanche est le premier jour de la semaine. Au Royaume-Uni, la semaine 1 est le 1 er janvier, les autres pays commencent la semaine 1 sur la semaine contenant le premier jeudi de l'année.

Vous pouvez trouver des informations plus générales sur http://en.wikipedia.org/wiki/Week#Week_number

4
Martin Liesén
$week_number = 40;
$year = 2008;

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

Cela échouera si $week_number est inférieur à 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
Nicolas

Cette fonction donnera les horodatages des jours de la semaine dans lesquels $ date est trouvé. Si $ date n'est pas donnée, cela suppose "maintenant". Si vous préférez des dates lisibles aux horodatages, passez un format de date dans le deuxième paramètre. Si vous ne commencez pas votre semaine le lundi (chanceux), passez un jour différent pour le troisième paramètre.

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

So week_dates () devrait retourner quelque chose comme ...

Array ( 
  [0] => 1234155600 
  [1] => 1234242000 
  [2] => 1234328400 
  [3] => 1234414800 
  [4] => 1234501200
  [5] => 1234587600
  [6] => 1234674000
)
2

Un autre code hehe:

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;
}
1
Miton Leon
$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>';

utiliser comme objet date () depuis php date php

0
Peter Breuls

J'avais la même question en utilisant seulement strftime au lieu de date comme point de départ, c’est-à-dire après avoir tiré un numéro de semaine de strftime en utilisant% W. Je voulais connaître la plage de dates de cette semaine - du lundi au dimanche (ou même un jour de départ). L'examen de plusieurs publications similaires et en particulier la mise à l'essai de certaines des approches ci-dessus ne m'ont pas conduit à la solution que je souhaitais. Bien sûr, j'ai peut-être mal compris quelque chose, mais je ne pouvais pas obtenir ce que je voulais.

Je voudrais donc partager ma solution. 

Ma première pensée a été que, étant donné la description de strftime% W,

numéro de semaine de l'année en cours, en commençant par le premier lundi sous la forme le premier jour de la première semaine

si j'établissais le premier lundi de chaque année, je pourrais calculer un tableau de plages de dates avec un index égal à la valeur de% W. Ensuite, je pourrais appeler la fonction en utilisant strftime.

Alors, voici:

La fonction:

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

    }   

?>

Exemple:

// 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"];

Sortie:

> 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

J'ai testé cela sur plusieurs années, dont 2018, l'année suivante où 1/1/2018 = lundi. Jusqu'ici, semble fournir la plage de dates correcte.

J'espère donc que cela aide.

Cordialement

0
codepuppy

Une autre solution:

//$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);
}

Exemple:

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

En dehors:

2014-02-10
2014-02-16
0
joan16v

J'ai trouvé un problème avec cette solution. Je devais mettre à zéro le numéro de semaine ou bien il était en train de se rompre.

Ma solution ressemble à ceci maintenant:

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

Pour ceux qui recherchent les jours de la semaine en fonction du numéro de la semaine (1-52) Partant du dimanche alors voici mon petit travail. Il prend en compte le fait de vérifier que la semaine est dans la bonne plage et complète les valeurs 1 à 9 pour que tout fonctionne correctement.

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