2011-02-01 16 views
34

He visto algunas variantes de esta pregunta, pero creo que esta no ha sido respondida aún.PHP get begin and end date of a week by weeknumber

necesito para obtener la fecha de inicio y fecha de fin de semana, elegido por año y el número de semanas (no una fecha)

ejemplo:

de entrada:

getStartAndEndDate($week, $year); 

de salida:

$return[0] = $firstDay; 
$return[1] = $lastDay; 

El valor de retorno será algo así como una matriz en la que la primera entrada es la fecha de inicio de la semana y la segunda es la fecha de finalización.

OPCIONAL: mientras estamos en ello, el formato de fecha es necesario que haya Y-n-j (formato normal de la fecha, no hay ceros a la izquierda

Yo he tratado de editar las funciones existentes que casi hice lo que quería, pero no he tenido suerte. hasta el momento.

favor me ayude a cabo, gracias por adelantado.

+1

StackOverflow no se trata de obtener tantas variantes como sea posible. Si puede encontrar una solución a partir de las variantes, no haga la pregunta. Si no puede resolverlo, le recomendamos que explique qué tan lejos ha llegado de las variantes. – Gordon

Respuesta

32
function getStartAndEndDate($week, $year) 
{ 

    $time = strtotime("1 January $year", time()); 
    $day = date('w', $time); 
    $time += ((7*$week)+1-$day)*24*3600; 
    $return[0] = date('Y-n-j', $time); 
    $time += 6*24*3600; 
    $return[1] = date('Y-n-j', $time); 
    return $return; 
} 
+8

El cálculo no es correcto. La semana 1 de 2014 es de '2013-12-30' a '2014-01-05', no de '2014-01-06' a '2014-01-12' esta es realmente la semana 2. –

+2

de hecho, esto va a suceder una semana libre. –

+0

Incorrecto porque se ignoró el Day Light Saving. –

0

Ha intentado PHP relative dates? podría funcionar.

+0

, ¿qué comando me sugerirías que use? 'strtotime ('primer día de la semana 12')'? – Pieter888

+0

@ Pieter888 esto no está funcionando y no está basado en el año –

+1

Quizás pueda encadenarlos. Pruebe '+ n semanas' para obtener la semana. Luego mira los documentos otra vez. También hay una forma de obtener un día de la semana. – Mikel

1

primero necesitamos un día de la semana por lo que si se conoce el número de la semana y kNO ala que una semana tiene siete días vamos a hacer lo que el

esta manera pickAday será un día en nuestra semana deseada.

Ahora, porque sabemos el año, podemos verificar qué día es ese. cosas son simples si solo necesitamos fechas más nuevas que la marca de tiempo de Unix Obtendremos la marca de tiempo de Unix para el primer día del año y agregaremos a eso 24*3600*$pickADay y todo es simple de aquí porque tenemos su marca de tiempo podemos saber qué día semana es y calcular la cabeza y la cola de esa semana en consecuencia.

Si queremos saber lo mismo de, por ejemplo, la 12ª semana de 1848, debemos utilizar otro enfoque, ya que no podemos obtener la marca de tiempo. Sabiendo que cada año un día avanza el significado de 1 semana (el 1 de noviembre del año pasado fue un domingo, este año es un lunes, excepción para los años bisiestos cuando avanza 2 días, creo que puede verificar eso). Qué haría si el año es anterior a 1970 que hacer una diferencia entre este año y el necesario para saber cuántos años hay, calcule el día de la semana ya que mi pickADay fue parte de 1970, y lo cambio un día laborable por cada . $shiftTimes = ($yearDifference + $numberOfLeapYears)%7, en la diferencia. cambie las contraseñas del día $ shiftTimes, entonces sabrá qué día de la semana fue ese día hace esos años, luego encontrará el weekhead y el weektail. Lo mismo se puede usar también para el futuro si parece más simple. Pruébalo si funciona y dime si no funciona.

+0

Gracias, claro que aclaro algo de mi confusión acerca de estas fechas. La respuesta dada por Roham Rafii confirma su teoría y les agradezco mucho a ambos. – Pieter888

0

Incluso si no desea utilizar una fecha específica, no puede escapar de ella. Puede calcular una semana basada SOLAMENTE en la fecha.

Pasos:

  1. obtener el primer día del año
  2. decidir cuándo comienza la primera semana (hay algunas reglas que incluyen primer jueves si no recuerdo.
  3. agregue algunas semanas (su primer parámetro). Zend_Date tiene una función add() donde puede agregar semanas, por ejemplo. Esto te dará el primer día de la semana.
  4. compensar y obtener el último día.

Recomendaría trabajar con un sistema de fechas consistente como Zend_Date o .

9

solución ligeramente más ordenado, utilizando el "[año] W [semanas] [días]" formato strtotime:

function getStartAndEndDate($week, $year) { 
    // Adding leading zeros for weeks 1 - 9. 
    $date_string = $year . 'W' . sprintf('%02d', $week); 
    $return[0] = date('Y-n-j', strtotime($date_string)); 
    $return[1] = date('Y-n-j', strtotime($date_string . '7')); 
    return $return; 
} 
-1
function getStartAndEndDate($week, $year) 
    { 
     $week_start = new DateTime(); 
     $week_start->setISODate($year,$week); 
     $return[0] = $week_start->format('d-M-Y'); 
     $time = strtotime($return[0], time()); 
     $time += 6*24*3600; 
     $return[1] = date('d-M-Y', $time); 
     return $return; 
    } 
+0

explique lo que hizo un poco más que simplemente publicando el código –

118

Usando DateTime clase:

function getStartAndEndDate($week, $year) { 
    $dto = new DateTime(); 
    $dto->setISODate($year, $week); 
    $ret['week_start'] = $dto->format('Y-m-d'); 
    $dto->modify('+6 days'); 
    $ret['week_end'] = $dto->format('Y-m-d'); 
    return $ret; 
} 

$week_array = getStartAndEndDate(52,2013); 
print_r($week_array); 

devoluciones :

Array 
(
    [week_start] => 2013-12-23 
    [week_end] => 2013-12-29 
) 

Explicación:

  • crear un nuevo objeto DateTime que por defecto es ahora() setISODate
  • llama para cambiar de objeto al primer día de $ semana de $ año en lugar de ahora()
  • fecha Formato como " ymd' y poner en $ ret [ 'week_start']
  • modificar el objeto mediante la adición de 6 días, que será el final de $ semana
  • fecha Formato como 'ymd' y poner en $ ret [ 'week_end']

Una versión más corta (obras en> = PHP5.3):

function getStartAndEndDate($week, $year) { 
    $dto = new DateTime(); 
    $ret['week_start'] = $dto->setISODate($year, $week)->format('Y-m-d'); 
    $ret['week_end'] = $dto->modify('+6 days')->format('Y-m-d'); 
    return $ret; 
} 

podría acortarse con class member access on instantiation de> = php5.4.

+8

Esta debería ser la respuesta aceptada, sin dudas. Es más rápido, más limpio y utiliza la clase interna DateTime(). – BizLab

+0

Para tener en cuenta, si decide devolver el objeto DateTime, necesita agregar clon antes de hacerlo o siempre obtendrá la fecha de modificación. '$ ret ['week_start'] = clone $ dto;' – Styledev

+1

Porque a veces necesitamos esto para mysql, necesitamos el tiempo también. Así que modifiqué esto ligeramente. Restablezca la hora, agregue 7 días y disminuya en 1 segundo. $ dto = new DateTime(); \t $ dto-> setISODate ($ year, $ week); \t $ dto-> setTime (0,0,0); \t $ ret ['week_start'] = $ dto-> format ('Y-m-d H: i: s'); \t $ dto-> modify ('+ 7 días'); \t $ dto-> modify ('- 1 sec'); \t $ ret ['week_end'] = $ dto-> format ('Y-m-d H: i: s'); –

1

El cálculo de Roham Rafii es incorrecto. Aquí es una solución a corto:

// week number to timestamp (first day of week number) 
function wn2ts($week, $year) { 
    return strtotime(sprintf('%dW%02d', $year, $week)); 
} 

si desea que el último día de la semana número, se pueden agregar hasta 6 * 24 * 3600

1

Ésta es una vieja pregunta, pero muchas de las respuestas publicadas anteriormente parece ser incorrecta . me ocurrió con mi propia solución:

function getStartAndEndDate($week, $year){ 
    $dates[0] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT))); 
    $dates[1] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT).' +6 days')); 
    return $dates; 
} 
0

camino más corto para hacerlo:

function week_date($week, $year){ 
    $date = new DateTime(); 
    return "first day of the week is ".$date->setISODate($year, $week, "1")->format('Y-m-d') 
    ."and last day of the week is ".$date->setISODate($year, $week, "7")->format('Y-m-d'); 
} 
echo week_date(12,2014); 
7

Podemos lograr esto fácilmente sin necesidad de cálculos adicionales aparte de las inherentes a la clase DateTime.

function getStartAndEndDate($year, $week) 
{ 
    return [ 
     (new DateTime())->setISODate($year, $week)->format('Y-m-d'), //start date 
     (new DateTime())->setISODate($year, $week, 7)->format('Y-m-d') //end date 
    ]; 
} 

La función setISODate() tiene tres argumentos: $year, $week y $day, respectivamente, en los que $day defecto es 1 - el primer día de la semana. Por lo tanto, aprobamos 7 para obtener la fecha exacta del 7º día del $week.

+0

La mejor solución, ¡agradable! – nights