php - qué - Cálculo de días de la semana dado un número de semana
que numero de semana estamos 2018 (13)
Dado que esta pregunta y la respuesta aceptada se publicaron, las clases de DateTime hacen mucho más simple:
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));
Esto tiene la ventaja adicional de cuidar los años bisiestos, etc.
Véalo funcionar . Incluyendo las difíciles semanas 1 y 53.
Dado un número de semana, por ejemplo, date -u +%W
, ¿cómo se calculan los días en esa semana a partir del lunes?
Ejemplo de salida rfc-3339 para la semana 40:
2008-10-06
2008-10-07
2008-10-08
2008-10-09
2008-10-10
2008-10-11
2008-10-12
Encontré un problema con esta solución. Tuve que rellenar con cero el número de la semana o de lo contrario se estaba rompiendo.
Mi solución se ve así ahora:
$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";
}
Esta función dará las marcas de tiempo de los días de la semana en que se encuentra $ date. Si $ date no se da, asume "ahora". Si prefiere las fechas legibles a las marcas de tiempo, pase un formato de fecha al segundo parámetro. Si no comienzas tu semana el lunes (afortunado), pasa un día diferente para el tercer parámetro.
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;
}
Entonces week_dates () debería devolver algo así como ...
Array (
[0] => 1234155600
[1] => 1234242000
[2] => 1234328400
[3] => 1234414800
[4] => 1234501200
[5] => 1234587600
[6] => 1234674000
)
Este cálculo varía en gran medida según el lugar donde viva. Por ejemplo, en Europa comenzamos la semana con un lunes, en EE. UU. El domingo es el primer día de la semana. En la semana 1 del Reino Unido es el 1 de enero, otros países comienzan la semana 1 en la semana que contiene el primer jueves del año.
Puede encontrar más información general en http://en.wikipedia.org/wiki/Week#Week_number
Otra solución:
//$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);
}
Ejemplo:
week_bounds("2014/02/10", $start, $end);
echo $start."<br>".$end;
Fuera:
2014-02-10
2014-02-16
Otro código jeje:
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;
}
Para aquellos que buscan los días de la semana dado el número de semana (1-52) A partir de un domingo , aquí está mi pequeño trabajo. Toma en cuenta que la semana está en el rango correcto y rellena los valores del 1 al 9 para que todo funcione.
$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]))); }
Si tienes Zend Framework, puedes usar la clase Zend_Date para hacer esto:
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>'';
Tenía la misma pregunta solo usando strftime en lugar de date como punto de partida, es decir, obteniendo un número de semana de strftime utilizando% WI. Quería saber el rango de fechas de esa semana, de lunes a domingo (o cualquier día de inicio). Una revisión de varios mensajes similares y, en particular, probando algunos de los enfoques anteriores no me llevaron a la solución que quería. Por supuesto que pude haber malinterpretado algo, pero no pude obtener lo que quería.
Por lo tanto, me gustaría compartir mi solución.
Mi primer pensamiento fue que dada la descripción de strftime% W es:
número de semana del año actual, comenzando con el primer lunes como el primer día de la primera semana
si estableciera el primer lunes de cada año, podría calcular una serie de intervalos de fechas con un índice igual al valor de% W. A partir de entonces, podría llamar a la función utilizando strftime.
Así que aquí va:
La función:
<?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;
}
?>
Ejemplo:
// 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"];
Salida:
> 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
Lo he probado durante varios años, incluido el año 2018, que es el próximo año cuando el 1/1/2018 = el lunes. Hasta ahora parece ofrecer el intervalo de fechas correcto.
Así que espero que esto ayude.
Saludos
PHP
$week_number = 40;
$year = 2008;
for($day=1; $day<=7; $day++)
{
echo date(''m/d/Y'', strtotime($year."W".$week_number.$day))."/n";
}
La publicación siguiente fue porque era un idiota que no leyó la pregunta correctamente, pero obtendrá las fechas en una semana a partir del lunes, dada la fecha, no el número de la semana.
En PHP , adaptado de esta publicación en la página del manual de fechas de 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;
}
La salida de week_from_monday(''07-10-2008'')
da:
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
)
<?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;
}
?>
$week_number = 40;
$year = 2008;
for($day=1; $day<=7; $day++)
{
echo date(''m/d/Y'', strtotime($year."W".$week_number.$day))."/n";
}
Esto fallará si $week_number
es menor que 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";
}
//==============================//
$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>'';
usar como objeto date () de php date php