¿Primer día de la semana en PHP?

124

Dado un MM-dd-yyyyformato de fecha , ¿alguien puede ayudarme a obtener el primer día de la semana?

Iggy Ma
fuente
44
¿Qué quieres decir con el primer día de la semana? ¿Te refieres a Sun, Mon? ¿O te refieres a la fecha del primer día de la semana?
Jeffrey Hines
2
El primer día de la semana es constante: es lunes (o posiblemente domingo). ¿Quiere decir que desea obtener la fecha del lunes anterior a una fecha arbitraria dada?
Jon Cram
¿Qué versión de PHP - 4 o 5?
Jon Cram
La fecha del domingo de la semana. php 5
Iggy Ma
Extraño, él pide una DateTimesolución y la mayoría de las respuestas no la proporcionan. =)
lin

Respuestas:

143

Esto es lo que estoy usando ...

$day = date('w');
$week_start = date('m-d-Y', strtotime('-'.$day.' days'));
$week_end = date('m-d-Y', strtotime('+'.(6-$day).' days'));

$ day contiene un número del 0 al 6 que representa el día de la semana (domingo = 0, lunes = 1, etc.).
$ week_start contiene la fecha del domingo de la semana actual como mm-dd-aaaa.
$ week_end contiene la fecha del sábado de la semana actual como mm-dd-aaaa.

JadedCore
fuente
1
pero, significa el comienzo y el final de 'esta semana', ¿verdad?
Oki Erie Rinaldi
¿Qué pasa si se da el número de semana? y quiero que devuelva la fecha de inicio y finalización de esa semana.
Oki Erie Rinaldi
1
@OkiErieRinaldi Probablemente debería abrir una nueva pregunta para recibir la atención adecuada.
JadedCore
¡No te preocupes, lo tengo @JadedCore!
Oki Erie Rinaldi
No estoy seguro de por qué el otro es más alto. ¡No funciona, pero este sí! 3v4l.org/q6kKY
Jason
67
strtotime('this week', time());

Reemplazar tiempo (). Los métodos del próximo domingo / último lunes no funcionarán cuando el día actual sea domingo / lunes.

laurentb
fuente
55
$monday = strtotime('last monday', strtotime('tomorrow'));
Lewis Buckley
this weekno funciona si necesita tener siempre un inicio de semana anterior, pero el comentario de @ LewisBuckley lo hace.
Smar
El segundo argumento time()es opcional si desea especificar hoy.
Si no
no funcionó para mí, tuve que ver una sintaxis ligeramente diferente para YTD, MTD, WTD.
Ron
66
Esta respuesta produce resultados inconsistentes, dependiendo de la versión de PHP utilizada: 3v4l.org/Z3k4E @ La solución de LewisBuckley es consistente para todas las versiones: 3v4l.org/Eeh9c
Chris Baker
62

strtotimeFunción muy simple de usar :

echo date("Y-m-d", strtotime('monday this week')), "\n";   

echo date("Y-m-d", strtotime('sunday this week')), "\n";

Difiere un poco entre las versiones de PHP :

Salida para 5.3.0 - 5.6.6, php7 @ 20140507 - 20150301, hhvm-3.3.1 - 3.5.1

2015-03-16
2015-03-22

Salida para 4.3.5 - 5.2.17

2015-03-23
2015-03-22

Salida para 4.3.0 - 4.3.4

2015-03-30
2015-03-29

Comparando en Edge-Cases

Las descripciones relativas como esta semana tienen su propio contexto. A continuación se muestra el resultado de esta semana lunes y domingo cuando es lunes o domingo:

$date = '2015-03-16'; // monday
echo date("Y-m-d", strtotime('monday this week', strtotime($date))), "\n";   
echo date("Y-m-d", strtotime('sunday this week', strtotime($date))), "\n";

$date = '2015-03-22'; // sunday
echo date("Y-m-d", strtotime('monday this week', strtotime($date))), "\n";   
echo date("Y-m-d", strtotime('sunday this week', strtotime($date))), "\n";

De nuevo, difiere un poco en las versiones de PHP :

Salida para 5.3.0 - 5.6.6, php7 @ 20140507 - 20150301, hhvm-3.3.1 - 3.5.1

2015-03-16
2015-03-22
2015-03-23
2015-03-29

Salida para 4.3.5 - 5.0.5, 5.2.0 - 5.2.17

2015-03-16
2015-03-22
2015-03-23
2015-03-22

Salida para 5.1.0 - 5.1.6

2015-03-23
2015-03-22
2015-03-23
2015-03-29

Salida para 4.3.0 - 4.3.4

2015-03-23
2015-03-29
2015-03-30
2015-03-29
Raja Rama Mohan Thavalam
fuente
¿Por qué esto no funciona para la fecha 2016-06-05, da las fechas de las próximas semanas?
1
Gracias por esto, ¿acabo de modificar este código para poder pasar un parámetro de fecha opcional $ dt = $ custom_date? strtotime ($ custom_date): time (); $ lunes = fecha ("Ymd", strtotime ('lunes esta semana', $ dt)); $ domingo = fecha ("Ymd", strtotime ('domingo esta semana', $ dt));
Ron Michael
47

Mantenlo simple :

<?php    
$dateTime = new \DateTime('2020-04-01');
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
$sunday = clone $dateTime->modify('Sunday this week');    
?>

Fuente: manual PHP

Nota: como algún usuario comentó, el valor de $ dateTime se modificará.

job3dot5
fuente
editar: error tipográfico o alguna sintaxis desconocida? de donde viene el \ $dateTime = new \DateTime('2012-05-14');
Sliq
2
Estoy haciendo esto para evitar cualquier conflicto con un posible objeto autocargado de su aplicación. Eso es como un camino absoluto o un camino relativo.
job3dot5
9
@Panique: la "sintaxis desconocida" es la sintaxis del espacio de nombres de PHP 5.3. El espacio de nombres le permite prefijar una clase con un espacio de nombres seguido de una barra diagonal inversa. Aquí lo está usando sin un espacio de nombres para especificar la DateTimeclase principal , lo que significa que el código funcionará incluso si tiene otra clase llamada DateTimeen el espacio de nombres actual.
Spudley
¿El nombre del día está siempre en inglés?
Marwelln
1
La parte de clonación no funciona correctamente. Primero debe clonar y luego realizar la operación en clonar si necesita uno original.
Farid Movsumov
25
$givenday = date("w", mktime(0, 0, 0, MM, dd, yyyy));

Esto le da el día de la semana de la fecha dada donde 0= domingo y 6= sábado. A partir de ahí, simplemente puede calcular hacia atrás hasta el día que desee.

Yuvalik
fuente
66
Esta respuesta devuelve si una fecha dada es el domingo o el lunes, etc. Pero, el interlocutor ha pedido la fecha del domingo de la semana de la fecha dada como se menciona en su comentario sobre la pregunta original.
Rakib
19

Esta pregunta necesita una buena respuesta DateTime : -

function firstDayOfWeek($date)
{
    $day = DateTime::createFromFormat('m-d-Y', $date);
    $day->setISODate((int)$day->format('o'), (int)$day->format('W'), 1);
    return $day->format('m-d-Y');
}

var_dump(firstDayOfWeek('06-13-2013'));

Salida:-

string '06-10-2013' (length=10)

Esto se ocupará de los límites del año y los años bisiestos.

vascowhite
fuente
18

EDITAR: el siguiente enlace ya no se ejecuta en la versión de PHP indicada. Se ejecuta en PHP 5.6, lo que mejora la fiabilidad del tiempo de ejecución, ¡pero no es perfecto! Los resultados en la tabla son resultados en vivo de PHP 5.6.

Para lo que vale, aquí hay un desglose del comportamiento inestable del tiempo de ejecución al determinar un marco de referencia consistente:

http://gamereplays.org/reference/strtotime.php

Básicamente, solo estas cadenas le darán de manera confiable la misma fecha, sin importar en qué día de la semana se encuentre actualmente cuando las llame:

strtotime("next monday");
strtotime("this sunday");
strtotime("last sunday"); 
AgmLauncher
fuente
El artículo también dio un código específico para usar: $ start_of_week = strtotime ("el próximo lunes - 1 semana"); // Regresará el lunes de la semana actual a partir de las 00:00:00 "$ end_of_week = strtotime (" próximo lunes - 1 segundo "); // Regresará el domingo de la semana actual que finaliza a las 23:59:59"
Scott M. Stolz
11

El siguiente código debería funcionar con cualquier fecha personalizada, solo usa el formato de fecha deseado.

$custom_date = strtotime( date('d-m-Y', strtotime('31-07-2012')) ); 
$week_start = date('d-m-Y', strtotime('this week last monday', $custom_date));
$week_end = date('d-m-Y', strtotime('this week next sunday', $custom_date));
echo '<br>Start: '. $week_start;
echo '<br>End: '. $week_end;

Probé el código con PHP 5.2.17 Resultados:

Start: 30-07-2012
End: 05-08-2012
Malagana
fuente
1
Vale la pena señalar que esto siempre devolverá el lunes anterior, por lo que si $ custom_date es un lunes, devolverá la fecha del lunes una semana antes.
Hill79
2
No funciona correctamente, hoy es domingo, los resultados son: Inicio: 09-09-2013 Final: 22-09-2013
usuario2019515
10

Asumiendo el lunes como el primer día de la semana, esto funciona:

echo date("M-d-y", strtotime('last monday', strtotime('next week', time())));
shasi kanth
fuente
1
"MM-dd-aaaa" no es lo mismo que "Ymd", por favor adapte su respuesta a los detalles de la pregunta.
Yevgeniy Afanasyev
1
date ("MM-dd-aaaa") muestra la fecha como: NovNov-0202-15151515. Espero que sea: date ("Mdy") que genera una fecha legible como: 02-nov-15
shasi kanth
"MM-dd-aaaa" proviene de la pregunta. Si no está seguro de lo que significa, hágala en un comentario a la pregunta. Gracias por modificar tu respuesta.
Yevgeniy Afanasyev
9

¿Qué tal esto?

$first_day_of_week = date('m-d-Y', strtotime('Last Monday', time()));
$last_day_of_week = date('m-d-Y', strtotime('Next Sunday', time()));
Birkof
fuente
8
El lunes pasado los lunes te darán el lunes anterior.
Ikke
8

Esto es lo que estoy usando para obtener el primer y último día de la semana desde cualquier fecha . En este caso, el lunes es el primer día de la semana ...

$date = date('Y-m-d') // you can put any date you want
$nbDay = date('N', strtotime($date));
$monday = new DateTime($date);
$sunday = new DateTime($date);
$monday->modify('-'.($nbDay-1).' days');
$sunday->modify('+'.(7-$nbDay).' days');
El obispo
fuente
1
Esa es la verdadera respuesta!
Manuel
1
¡Funciona de maravilla!
Liga
6

Aquí estoy considerando el domingo como primer día y el sábado como último día de la semana.

$m = strtotime('06-08-2012');  
$today =   date('l', $m);  
$custom_date = strtotime( date('d-m-Y', $m) );   
if ($today == 'Sunday') {  
   $week_start = date("d-m-Y", $m);  
} else {  
  $week_start = date('d-m-Y', strtotime('this week last sunday', $custom_date));  
}  

if ($today == 'Saturday') {  
  $week_end = date("d-m-Y", $m);
} else {  
  $week_end = date('d-m-Y', strtotime('this week next saturday', $custom_date));  
}
echo '<br>Start: '. $week_start;  
echo '<br>End: '. $week_end;  

Salida:

Inicio: 05-08-2012
Fin: 11-08-2012

Irshad Sheikh
fuente
5

¿Qué tal esto?

$day_of_week = date('N', strtotime($string_date));
$week_first_day = date('Y-m-d', strtotime($string_date . " - " . ($day_of_week - 1) . " days"));
$week_last_day = date('Y-m-d', strtotime($string_date . " + " . (7 - $day_of_week) . " days"));
Tarquinius Superbus
fuente
4

Prueba esto:

function week_start_date($wk_num, $yr, $first = 1, $format = 'F d, Y')
{
    $wk_ts  = strtotime('+' . $wk_num . ' weeks', strtotime($yr . '0101'));
    $mon_ts = strtotime('-' . date('w', $wk_ts) + $first . ' days', $wk_ts);
    return date($format, $mon_ts);
}

$sStartDate = week_start_date($week_number, $year);
$sEndDate   = date('F d, Y', strtotime('+6 days', strtotime($sStartDate)));

(de este hilo del foro )

James Skidmore
fuente
¿Cómo obtengo el número de semana y el año en todo eso? Tengo una fecha de cadena en formato MM-dd-aaaa
Iggy Ma
4

Esta es la solución más corta y legible que encontré:

    <?php
    $weekstart = strtotime('monday this week');
    $weekstop = strtotime('sunday this week 23:59:59');
    //echo date('d.m.Y H:i:s', $weekstart) .' - '. date('d.m.Y H:i:s', $weekstop);
    ?>

strtotimees más rápido que new DateTime()->getTimestamp().

dipser
fuente
Esto es perfecto, vea mi solución para las fechas de Australia / Reino Unido
zanderwar
4

Solo usa date($format, strtotime($date,' LAST SUNDAY + 1 DAY'));

Kondziutek
fuente
2

La siguiente función de la versión anterior de PHP dada 5.3 le da un primer día de la semana de la fecha dada (en este caso - domingo, 2013-02-03):

<?php
  function startOfWeek($aDate){
    $d=strtotime($aDate);
    return strtotime(date('Y-m-d',$d).' - '.date("w",$d).' days');
  }

  echo(date('Y-m-d',startOfWeek("2013-02-07")).'
');
?>
David Jashi
fuente
2
$today_day = date('D'); //Or add your own date
$start_of_week = date('Ymd');
$end_of_week = date('Ymd');

if($today_day != "Mon")
    $start_of_week = date('Ymd', strtotime("last monday"));

if($today_day != "Sun")
                    $end_of_week = date('Ymd', strtotime("next sunday"));
usuario195257
fuente
2
$monday = date('d-m-Y',strtotime('last monday',strtotime('next monday',strtotime($date))));

Primero debe obtener el próximo lunes y luego obtener el 'último lunes' del próximo lunes. Entonces, si la fecha dada es el lunes, devolverá la misma fecha no la semana pasada el lunes.

Veneno Fedy
fuente
2

Si quieres el lunes como el comienzo de tu semana, haz esto:

$date = '2015-10-12';
$day = date('N', strtotime($date));
$week_start = date('Y-m-d', strtotime('-'.($day-1).' days', strtotime($date)));
$week_end = date('Y-m-d', strtotime('+'.(7-$day).' days', strtotime($date)));
Henry Weber
fuente
¿Qué hace que esto sea preferible a esta respuesta , o esta respuesta ? Me parece que hay más que suficientes opciones en las otras 30 respuestas ...
Mogsdad
Gracias. Esta es una solución simple y funciona como un encanto.
Oleg Popov
2

Una forma inteligente de hacerlo es dejar que PHP maneje las diferencias de zona horaria y el horario de verano (DST). Déjame mostrarte cómo hacer esto.

Esta función generará todos los días de lunes a viernes, inclusive (útil para generar días laborables):

class DateTimeUtilities {
    public static function getPeriodFromMondayUntilFriday($offset = 'now') {
        $now = new \DateTimeImmutable($offset, new \DateTimeZone('UTC'));
        $today = $now->setTime(0, 0, 1);

        $daysFromMonday = $today->format('N') - 1;

        $monday = $today->sub(new \DateInterval(sprintf('P%dD', $daysFromMonday)));
        $saturday = $monday->add(new \DateInterval('P5D'));

        return new \DatePeriod($monday, new \DateInterval('P1D'), $saturday);
    }
}

foreach (DateTimeUtilities::getPeriodFromMondayUntilFriday() as $day) {
    print $day->format('c');
    print PHP_EOL;
}

Esto devolverá las horas de lunes a viernes de la semana actual. Para hacer lo mismo para una fecha arbitraria, pase una fecha como parámetro a DateTimeUtilities ::getPeriodFromMondayUntilFriday, por lo tanto:

foreach (DateTimeUtilities::getPeriodFromMondayUntilFriday('2017-01-02T15:05:21+00:00') as $day) {
    print $day->format('c');
    print PHP_EOL;
}

//prints 
//2017-01-02T00:00:01+00:00
//2017-01-03T00:00:01+00:00
//2017-01-04T00:00:01+00:00
//2017-01-05T00:00:01+00:00
//2017-01-06T00:00:01+00:00

¿Solo le interesa el lunes, como preguntó el OP?

$monday = DateTimeUtilities::getPeriodFromMondayUntilFriday('2017-01-02T15:05:21+00:00')->getStartDate()->format('c');
print $monday;
// prints
//2017-01-02T00:00:01+00:00
Nino Škopac
fuente
1

Analiza la fecha usando strptime()y usa date()el resultado:

date('N', strptime('%m-%d-%g', $dateString));
soulmerge
fuente
1
<?php
/* PHP 5.3.0 */

date_default_timezone_set('America/Denver'); //Set apprpriate timezone
$start_date = strtotime('2009-12-15'); //Set start date

//Today's date if $start_date is a Sunday, otherwise date of previous Sunday
$today_or_previous_sunday = mktime(0, 0, 0, date('m', $start_date), date('d', $start_date), date('Y', $start_date)) - ((date("w", $start_date) ==0) ? 0 : (86400 * date("w", $start_date)));

//prints 12-13-2009 (month-day-year)
echo date('m-d-Y', $today_or_previous_sunday);

?>

(Nota: MM, dd y aaaa en la pregunta no son la sintaxis estándar del formato de fecha php; no puedo estar seguro de lo que significa, así que configuré $ start_date con ISO año-mes-día)

micahwittman
fuente
1

Otra forma de hacerlo ...

$year = '2014';
$month = '02';
$day = '26';

$date = DateTime::createFromFormat('Y-m-d H:i:s', $year . '-' . $month . '-' . $day . '00:00:00');
$day = date('w', $date->getTimestamp());

// 0=Sunday 6=Saturday
if($day!=0){

   $newdate = $date->getTimestamp() - $day * 86400;  //86400 seconds in a day

   // Look for DST change 
   if($old = date('I', $date->getTimestamp()) != $new = date('I', $newdate)){
       if($old == 0){
           $newdate -= 3600;  //3600 seconds in an hour
       } else {
           $newdate += 3600;
       }
   }

   $date->setTimestamp($newdate);
}

echo $date->format('D Y-m-d H:i:s');
Michael Pawlowsky
fuente
1

La forma más fácil de obtener el primer día (lunes) de la semana actual es:

strtotime("next Monday") - 604800;

donde 604800 - es el recuento de segundos en 1 semana (60 * 60 * 24 * 7).

Este código se obtiene el próximo lunes y lo disminuye durante 1 semana. Este código funcionará bien en cualquier día de la semana. Incluso si hoy es lunes.

Anton Popov
fuente
1

Esto me pareció bastante frustrante dado que mi zona horaria es australiana y que strtotime()odia las fechas en el Reino Unido.

Si el día actual es un domingo, strtotime("monday this week")volverá el día siguiente.

Para superar esto:

Precaución : esto solo es válido para fechas de Australia / Reino Unido

$startOfWeek = (date('l') == 'Monday') ? date('d/m/Y 00:00') : date('d/m/Y', strtotime("last monday 00:00"));
$endOfWeek = (date('l') == 'Sunday') ? date('d/m/Y 23:59:59') : date('d/m/Y', strtotime("sunday 23:59:59"));
Zanderwar
fuente
2
Esto funciona para fechas de EE. UU. También. He probado esto con la zona horaria de Nueva York.
Jayesh D
Mientras el domingo no sea su primer día de la semana (lunes en Australia / Reino Unido), estará bien.
zanderwar
1

Aquí hay una línea para el primer día de la semana pasada y el último día de la semana pasada como un DateTimeobjeto.

$firstDay = (new \DateTime())->modify(sprintf('-%d day', date('w') + 7))
                             ->setTime(0, 0, 0);
$lastDay = (new \DateTime())->modify(sprintf('-%d day', date('w') + 1))
                            ->setTime(23, 59, 59);
David Baucum
fuente
1
$string_date = '2019-07-31';
echo $day_of_week = date('N', strtotime($string_date));
echo $week_first_day = date('Y-m-d', strtotime($string_date . " - " . ($day_of_week - 1) . " days"));
echo $week_last_day = date('Y-m-d', strtotime($string_date . " + " . (7 - $day_of_week) . " days"));
Syed Urooj Waqar
fuente
Útil cuando tenemos lunes como el primer día de la semana (lunes a domingo).
Kamran Mushtaq
0

Me he encontrado con esta pregunta varias veces y siempre me ha sorprendido que las funciones de fecha no lo hagan más fácil o más claro. Aquí está mi solución para PHP5 que usa la DateTimeclase:

/**
 * @param DateTime $date A given date
 * @param int $firstDay 0-6, Sun-Sat respectively
 * @return DateTime
 */
function getFirstDayOfWeek(DateTime $date, $firstDay = 0) {
    $offset = 7 - $firstDay;
    $ret = clone $date;
    $ret->modify(-(($date->format('w') + $offset) % 7) . 'days');
    return $ret;
}

Necesario clonar para evitar alterar la fecha original.

contrebis
fuente
0

Qué pasa:

$date = "2013-03-18"; 
$searchRow = date("d.m.Y", strtotime('last monday',strtotime($date." + 1 day")));
echo "for date " .$date ." we get this monday: " ;echo $searchRow; echo '<br>';

No es la mejor manera, pero lo probé y si estoy en esta semana obtengo el lunes correcto, y si estoy en un lunes, obtendré ese lunes.

CaféJunky
fuente