Calcul des jours de la semaine en fonction 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
13 réponses
PHP
$week_number = 40;
$year = 2008;
for($day=1; $day<=7; $day++)
{
echo date('m/d/Y', strtotime($year."W".$week_number.$day))."\n";
}
Ci-dessous post était parce que j'étais un idiot qui n'a pas lu la question correctement, mais obtiendra les dates dans une semaine à partir de lundi, étant donné la date, pas le numéro de la semaine..
En PHP , adapté de ce post sur la page de manuel 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;
}
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
)
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>';
Puisque cette question et la réponse acceptée ont été postées, les classes DateTime rendent cela beaucoup plus simple à faire: -
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 travail. Y compris les semaines difficiles 1 et 53.
Ce calcul varie en grande partie selon l'endroit où vous vivez. Par exemple, en Europe, nous commençons la semaine avec un lundi, en NOUS, le dimanche est le premier jour de la semaine. Au Royaume-Uni, la semaine 1 est le 1er janvier, d'autres pays commencent la semaine 1 la semaine contenant le premier jeudi de l'année.
Vous pouvez trouver des informations plus générales à http://en.wikipedia.org/wiki/Week#Week_number
Cette fonction donnera les horodatages des jours de la semaine où $date est trouvé. Si $date n'est pas donné, il suppose " maintenant."Si vous préférez les dates lisibles aux horodatages, Passez un format de date dans le second 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;
}
Donc week_dates () devrait renvoyer quelque chose comme...
Array (
[0] => 1234155600
[1] => 1234242000
[2] => 1234328400
[3] => 1234414800
[4] => 1234501200
[5] => 1234587600
[6] => 1234674000
)
$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";
}
//==============================//
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;
}
, j'ai trouvé un problème avec cette solution. J'ai dû zero-pad le numéro de la semaine ou bien il se cassait.
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";
}
Pour ceux qui recherchent les jours de la semaine étant donné le numéro de la semaine (1-52) A partir d'un dimanche alors voici mon petit travail autour. Prend en compte la vérification de la semaine est dans la bonne plage et tampons les valeurs 1-9 pour garder tout cela fonctionne.
$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]))); }
J'ai eu la même question en utilisant seulement strftime au lieu de date comme point de départ, c'est - à-dire avoir dérivé un numéro de semaine de strftime en utilisant %W je voulais connaître la plage de dates pour cette semaine-du lundi au dimanche (ou même n'importe quel jour de départ). Un examen de plusieurs messages similaires et en particulier essayer quelques-unes des approches ci-dessus ne m'a pas amené à la solution que je voulais. 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 était que compte tenu de la description de strftime %W est:
Numéro de semaine de l'année en cours, commençant par le premier lundi le premier jour de la première semaine
Si j'établissais Quel est le premier lundi de chaque année, je pourrais calculer un tableau de plages de dates avec un index égal à la valeur de %W. par la suite, je pourrais appeler la fonction en utilisant strftime.
Alors voici:
Le 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, y compris 2018 qui est l'année suivante lorsque 1/1/2018 = lundi. Jusqu'à présent semble fournir la plage de dates correcte.
J'espère donc que cela aide.
Cordialement
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;
Out:
2014-02-10
2014-02-16
$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 () de php Date php
<?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;
}
?>