2009-05-29 39 views
27

Estoy tratando de obtener el rango de semana utilizando el domingo como fecha de inicio, y una fecha de referencia, por ejemplo $date, pero parece que no puedo resolverlo.Obtener días de inicio y finalización para una semana determinada en PHP

Por ejemplo, si tuviera $ date como 2009-05-01, obtendría 2009-04-26 y 2009-05-02. 2009-05-10 arrojaría 2009-05-10 y 2009-05-16. Mi código actual se parece a esto (no puedo recordar dónde lo levanté a partir, como se me ha olvidado poner la url en mis comentarios):

function x_week_range(&$start_date, &$end_date, $date) 
{ 
    $start_date = ''; 
    $end_date = ''; 
    $week = date('W', strtotime($date)); 
    $week = $week; 

    $start_date = $date; 

    $i = 0; 
    while(date('W', strtotime("-$i day")) >= $week) { 
     $start_date = date('Y-m-d', strtotime("-$i day")); 
     $i++; 
    } 

    list($yr, $mo, $da) = explode('-', $start_date); 

    $end_date = date('Y-m-d', mktime(0, 0, 0, $mo, $da + 6, $yr)); 
} 

me di cuenta de todo lo que hizo fue añadir 7 días a la corriente fecha. ¿Cómo harías esto?

Respuesta

81

me gustaría tener advantange de strtotime genialidad de PHP:

function x_week_range(&$start_date, &$end_date, $date) { 
    $ts = strtotime($date); 
    $start = (date('w', $ts) == 0) ? $ts : strtotime('last sunday', $ts); 
    $start_date = date('Y-m-d', $start); 
    $end_date = date('Y-m-d', strtotime('next saturday', $start)); 
} 

analizadas en los datos que nos ha facilitado y funciona. Sin embargo, no me gusta particularmente toda la cosa de referencia que tienes. Si esta era mi función, tendría que ser de esta manera:

function x_week_range($date) { 
    $ts = strtotime($date); 
    $start = (date('w', $ts) == 0) ? $ts : strtotime('last sunday', $ts); 
    return array(date('Y-m-d', $start), 
       date('Y-m-d', strtotime('next saturday', $start))); 
} 

y lo llaman así:

list($start_date, $end_date) = x_week_range('2009-05-10'); 

No soy un gran fan de hacer las matemáticas para cosas como esta. Las fechas son complicadas y prefiero que PHP lo resuelva.

+2

que utiliza lo siguiente para obtener la última fecha de domingo formateada: fecha ('Ym-d', strtotime ('el último domingo')) –

+3

¡Prueba la clase DateTime de PHP5! – jjwdesign

+0

@John M, vea mi comentario a continuación sobre cómo "el último domingo" puede ser problemático si hoy es domingo y desea __esta__ semana. – cdmo

0

Para ser honesto, no tengo problemas para entender el código que envió;)

supongo que algo como esto debe hacer el truco:

function get_week($date) { 
     $start = strtotime($date) - strftime('%w', $date) * 24 * 60 * 60; 
     $end = $start + 6 * 24 * 60 * 60; 
     return array('start' => strftime('%Y-%m-%d', $start), 
        'end' => strftime('%Y-%m-%d', $end)); 
} 
0

Sin hacer tanto la manipulación de cadenas, se pueden hacer algunas matemáticas simples en las marcas de tiempo.

function getDateRange(&$start, &$end, $date) { 
    $seconds_in_day = 86400; 
    $day_of_week = date("w", $date); 
    $start = $date - ($day_of_week * $seconds_in_day); 
    $end = $date + ((6 - $day_of_week) * $seconds_in_day); 
} 
2

aquí está mi versión, que utiliza una idea similar a la arcilla de:

/** 
* Start of the week 
* 
* 0 = Sun, 1 = Mon, etc. 
*/ 
define('WEEK_START', 0); 

/** 
* Determine the start and end dates for 
* the week in which the specified date 
* falls 
* 
* @param $date Date in week 
* @param $start Week start (out) 
* @param $end Week end (out) 
*/ 
function week_bounds($date, &$start, &$end) { 
    $date = strtotime($date); 
    // Find the start of the week, working backwards 
    $start = $date; 
    while(date('w', $start) > WEEK_START) { 
     $start -= 86400; // One day 
    } 
    // End of the week is simply 6 days from the start 
    $end = date('Y-m-d', $start + (6 * 86400)); 
    $start = date('Y-m-d', $start); 
} 

ligeramente probado. El código puede no ser a prueba de balas, o manejar fechas en el pasado o en el futuro. Úselo bajo su propio riesgo. No sumerja el código en agua. No muestre el código a los que están nerviosos o con odio al signo de dólar. No probado en animales. Seguro para el uso de los vegetarianos. El autor garantiza que el código nunca, alguna vez te hablará. En el caso improbable de que el código intente involucrarlo en una conversación, el autor le aconseja no tener en cuenta ninguno de los consejos que brinda.

8

Al parecer, 'w' formatear valor de fecha() o el método de formato de un objeto DateTime devolverá el día de la semana como un número (por defecto, 0 = domingo, 1 = Lunes, etc)

Puede tomar esto y restar su valor como días del día actual para encontrar el comienzo de la semana.

$start_date = new DateTime("2009-05-13"); 
$day_of_week = $start_date->format("w"); 

$start_date->modify("-$day_of_week day"); 

$ fecha_inicial ahora será igual al domingo de esa semana, desde allí se puede añadir de 7 días para llegar al final de la semana o lo que usted quiera.

+0

lo mismo se puede hacer con la función Fecha: '$ day_of_week date ('w', strtotime ($ start_date));' '$ sunday = date ('Ym-d', strtotime ('-'. $ Day_of_week . 'days', strtotime ($ start_date))); ' –

1

Al tratar de encontrar una versión más simplificada de la respuesta aceptada por Paolo Bergantino, descubrí una muy buena manera de hacer esto:

function x_week_range2($date) { 
    $ts = strtotime($date); 
    $start = strtotime('sunday this week -1 week', $ts); 
    $end = strtotime('sunday this week', $ts); 
    return array(date('Y-m-d', $start), date('Y-m-d', $end)); 
} 

El 'Domingo esta semana' cadena siempre significa "The Sunday en el final de esta semana. " Si se utiliza en una marca de tiempo que cae en domingo, será el siguiente domingo. Esto le permite evitar la necesidad del operador ternario en la solución de Paola.

18

Para todos los que todavía usan mktime(), strtotime() y otras funciones de PHP ... prueben la clase PHP5 DateTime. Al principio tenía dudas, pero es realmente fácil de usar. No te olvides de usar clone() para copiar tus objetos.

Editar: Este código fue editado recientemente para manejar el caso donde el día actual es el domingo. En ese caso, tenemos que conseguir el pasado sábado y luego agregar un día para obtener el domingo.

$dt_min = new DateTime("last saturday"); // Edit 
$dt_min->modify('+1 day'); // Edit 
$dt_max = clone($dt_min); 
$dt_max->modify('+6 days'); 

Luego formatee como lo necesite.

echo 'This Week ('.$dt_min->format('m/d/Y').'-'.$dt_max->format('m/d/Y').')'; 

Asegúrese de configurar su zona horaria desde el principio de su código.

date_default_timezone_set('America/New_York'); 
+1

A menos que esté leyendo esto mal, no estoy seguro si esta lógica funcionará si hoy es domingo. Si hoy es domingo y usted hace un objeto 'DateTime' del 'último domingo', PHP devolverá el domingo anterior, no el actual. Entonces, si la fecha de hoy es 2/28/2016, el código anterior se repetirá "Esta semana 21/02/2016 - 27/02/2016" (efectivamente la semana anterior, de lunes a sábado se escondería este problema. Sugeriría algo como '$ dt_min = new DateTime (" el último sábado + 24 horas ");' – cdmo

+1

¡Buena captura de cdmo! Cambié el código para reflejarlo. – jjwdesign

3

base a la respuesta de @ jjwdesign, he desarrollado una función que puede calcular el comienzo y el final de una semana para una fecha específica utilizando la clase DateTime. FUNCIONARÁ EN PHP 5.3.0 ++

La diferencia es que puede establecer el día que desea como el "comienzo" entre 0 (lunes) y 6 (domingo).

Aquí está la función:

if(function_exists('grk_Week_Range') === FALSE){ 
    function grk_Week_Range($DateString, $FirstDay=6){ 
     # Valeur par défaut si vide 
     if(empty($DateString) === TRUE){ 
      $DateString = date('Y-m-d'); 
     } 

     # On va aller chercher le premier jour de la semaine qu'on veut 
     $Days = array(
      0 => 'monday', 
      1 => 'tuesday', 
      2 => 'wednesday', 
      3 => 'thursday', 
      4 => 'friday', 
      5 => 'saturday', 
      6 => 'sunday' 
     ); 

     # On va définir pour de bon le premier jour de la semaine  
     $DT_Min = new DateTime('last '.(isset($Days[$FirstDay]) === TRUE ? $Days[$FirstDay] : $Days[6]).' '.$DateString); 
     $DT_Max = clone($DT_Min); 

     # On renvoie les données 
     return array(
      $DT_Min->format('Y-m-d'), 
      $DT_Max->modify('+6 days')->format('Y-m-d') 
     ); 
    } 
} 

Resultados:

print_r(grk_Week_Range('2013-08-11 16:45:32', 0)); 
print_r(grk_Week_Range('2013-08-11 16:45:32', 1)); 
print_r(grk_Week_Range('2013-08-11 16:45:32', 2)); 
print_r(grk_Week_Range('2013-08-11 16:45:32', 3)); 
print_r(grk_Week_Range('2013-08-11 16:45:32', 4)); 
print_r(grk_Week_Range('2013-08-11 16:45:32', 5)); 
print_r(grk_Week_Range('2013-08-11 16:45:32', 6)); 

Array 
(
    [0] => 2013-07-29 
    [1] => 2013-08-04 
) 
Array 
(
    [0] => 2013-07-30 
    [1] => 2013-08-05 
) 
Array 
(
    [0] => 2013-07-31 
    [1] => 2013-08-06 
) 
Array 
(
    [0] => 2013-07-25 
    [1] => 2013-07-31 
) 
Array 
(
    [0] => 2013-07-26 
    [1] => 2013-08-01 
) 
Array 
(
    [0] => 2013-07-27 
    [1] => 2013-08-02 
) 
Array 
(
    [0] => 2013-07-28 
    [1] => 2013-08-03 
) 
-1

desde PHP DateTime doc:

<?php 
$date = new DateTime(); 

$date->setISODate(2008, 2); 
$startDay = $date->format('Y-m-d'); 

$date->setISODate(2008, 2, 7); 
$endDay = $date->format('Y-m-d'); 
?> 
1

Utilice esta opción para obtener el número de "semanas" de una fecha determinada.

//October 29, 2009 is my birthday 
echo $week date('W', strtotime('2009-10-29')); 
//OUTPUT: 44 
//October 29 is the 44th week in the year 2009 

Ahora pasan los parámetros para la función getWeekDates como "año (2009)" y "$ semana".

function getWeekDates($year, $week, $start=true){ 
     $from = date("Y-m-d", strtotime("{$year}-W{$week}-1")); //Returns the date of monday in week 
     $to = date("Y-m-d", strtotime("{$year}-W{$week}-7")); //Returns the date of sunday in week 

     if($start) { 
      return $from; 
     } else { 
      return $to; 
     } 
     //return "Week {$week} in {$year} is from {$from} to {$to}."; 
    } 

Para más información por favor consulte este enlace http://blog.ekini.net/2009/07/09/php-get-start-and-end-dates-of-a-week-from-datew/

0

Basado en la versión de David Bélanger (desafortunadamente, mi representante. No me permitirá enviar comentario como reacción a su puesto ..).

Cuando la fecha de entrada es el lunes y el primer día de la semana se establece como el lunes, la versión original devuelve la semana anterior, no la actual. Aquí está la pequeña solución (con el resto de orig.función):

if(function_exists('grk_Week_Range') === FALSE){ 
function grk_Week_Range($DateString, $FirstDay=6){ 

    if(empty($DateString) === TRUE){ 
     $DateString = date('Y-m-d'); 
    } 

    # fix 
    $dayOfWeek = date('N', strtotime($DateString)); 
    if ($dayOfWeek == ($FirstDay +1)) { $whichWeek = 'this '; } 
    else { $whichWeek = 'last '; } 

    $Days = array(
     0 => 'monday', 
     1 => 'tuesday', 
     2 => 'wednesday', 
     3 => 'thursday', 
     4 => 'friday', 
     5 => 'saturday', 
     6 => 'sunday' 
    ); 

    # fix 
    $DT_Min = new DateTime($whichWeek.(isset($Days[$FirstDay]) === TRUE ? $Days[$FirstDay] : $Days[6]).' '.$DateString); 
    $DT_Max = clone($DT_Min); 

    return array(
     $DT_Min->format('Y-m-d'), 
     $DT_Max->modify('+6 days')->format('Y-m-d') 
    ); 
} 
} 
1

Ahora puede utilizar DateTime para obtener fechas de inicio/final de la semana (s)

function getDateRangeForAllWeeks($start, $end){ 
    $fweek = getDateRangeForWeek($start); 
    $lweek = getDateRangeForWeek($end); 
    $week_dates = []; 
    while($fweek['sunday']!=$lweek['sunday']){ 
     $week_dates [] = $fweek; 
     $date = new DateTime($fweek['sunday']); 
     $date->modify('next day'); 

     $fweek = getDateRangeForWeek($date->format("Y-m-d")); 
    } 
    $week_dates [] = $lweek; 

    return $week_dates; 
} 

function getDateRangeForWeek($date){ 
    $dateTime = new DateTime($date); 
    $monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week'); 
    $sunday = clone $dateTime->modify('Sunday this week'); 
    return ['monday'=>$monday->format("Y-m-d"), 'sunday'=>$sunday->format("Y-m-d")]; 
} 

Uso

print_r(getDateRangeForWeek("2016-05-07")); 

print_r(getDateRangeForAllWeeks("2015-11-07", "2016-02-15")); 
Cuestiones relacionadas