Obter o primeiro dia da semana em PHP?

124

Dado um MM-dd-yyyyformato de data , alguém pode me ajudar a obter o primeiro dia da semana?

Iggy Ma
fonte
4
O que você quer dizer com primeiro dia da semana? Você quer dizer Sun, Mon? Ou você quer dizer a data do primeiro dia da semana?
Jeffrey Hines
2
O primeiro dia da semana é constante: é segunda-feira (ou possivelmente domingo). Você quer dizer que deseja obter a data da segunda-feira anterior a uma data arbitrária?
11139 Jon Cram
Qual versão do PHP - 4 ou 5?
11139 Jon Cram
a data do domingo da semana. php 5
Iggy Ma
Estranho, ele está pedindo uma DateTimesolução e a maioria das respostas não a fornece. =)
lin 15/11

Respostas:

143

Aqui está o que estou usando ...

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

$ day contém um número de 0 a 6, representando o dia da semana (domingo = 0, segunda-feira = 1, etc.).
$ week_start contém a data do domingo da semana atual como mm-dd-aaaa.
$ week_end contém a data do sábado da semana atual como mm-dd-aaaa.

JadedCore
fonte
1
mas, isso significa o começo e o fim de 'esta semana', certo?
Oki Erie Rinaldi
e se o número da semana for fornecido? e eu quero que ele retorne a data de início e fim da semana.
Oki Erie Rinaldi
1
@OkiErieRinaldi Você provavelmente deve abrir uma nova pergunta para receber a devida atenção.
JadedCore
Não se preocupe, eu entendi @JadedCore!
Oki Erie Rinaldi
Não sei por que o outro é mais alto. Não funciona, mas este funciona! 3v4l.org/q6kKY
Jason
67
strtotime('this week', time());

Substitua a hora (). Os métodos do próximo domingo / segunda-feira não funcionarão quando o dia atual for domingo / segunda-feira.

laurentb
fonte
55
$monday = strtotime('last monday', strtotime('tomorrow'));
Lewis Buckley
this weeknão funciona se você precisa ter sempre o início da semana anterior, mas o comentário de @ LewisBuckley o faz.
Smar
O segundo argumento time()é opcional se você desejar especificar hoje.
Ifnot
não funcionou para mim, eu tive que ver uma sintaxe um pouco diferente para YTD, MTD, WTD.
Ron
6
Esta resposta produz resultados inconsistentes, dependendo da versão do PHP usado: 3v4l.org/Z3k4E de @ LewisBuckley solução é consistente para todas as versões: 3v4l.org/Eeh9c
Chris Baker
62

strtotimeFunção muito simples de usar :

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

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

Difere um pouco entre as versões do PHP :

Saída para 5.3.0 - 5.6.6, php7 @ 20140507 - 20150301, hhvm-3.3.1 - 3.5.1

2015-03-16
2015-03-22

Saída para 4.3.5 - 5.2.17

2015-03-23
2015-03-22

Saída para 4.3.0 - 4.3.4

2015-03-30
2015-03-29

Comparando em casos de borda

Descrições relativas como esta semana têm seu próprio contexto. A seguir, é mostrada a saída desta semana de segunda a domingo, quando é segunda ou 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";

No entanto, difere um pouco nas versões do PHP :

Saída 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

Saída 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

Saída para 5.1.0 - 5.1.6

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

Saída para 4.3.0 - 4.3.4

2015-03-23
2015-03-29
2015-03-30
2015-03-29
Raja Rama Mohan Thavalam
fonte
por que isso não está funcionando para a data 05/06/2016, está dando datas nas próximas semanas.
1
Obrigado por isso, apenas modifiquei esse código para poder passar um parâmetro opcional de data $ dt = $ custom_date? strtotime ($ custom_date): time (); $ segunda-feira = data ("Ymd", strtotime ('segunda-feira desta semana', $ dt)); $ domingo = data ("Ymd", strtotime ('domingo esta semana', $ dt));
Ron Michael
47

Mantenha simples :

<?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');    
?>

Fonte: Manual do PHP

Nota: como algum usuário comentou, o valor $ dateTime será modificado.

job3dot5
fonte
edit: erro de digitação ou alguma sintaxe desconhecida? de onde vem o \? $dateTime = new \DateTime('2012-05-14');
Sliq
2
Estou fazendo isso para evitar qualquer conflito com um possível objeto carregado automaticamente do seu aplicativo. Isso é como caminho absoluto ou caminho relativo.
job3dot5
9
@ Panique - a "sintaxe desconhecida" é a sintaxe de espaço para nome do PHP 5.3. O namespacing permite prefixar uma classe com um namespace seguido por uma barra invertida. Aqui ele está usando-o sem um espaço para nome para especificar a DateTimeclasse principal , o que significa que o código funcionará mesmo se você tiver outra classe chamada DateTimeno espaço para nome atual.
Spudley 14/05
O nome do dia está sempre em inglês?
Marwelln
1
A parte do clone não está funcionando corretamente. Você deve clonar primeiro e, em seguida, fazer operação no clone, se precisar de um original.
Farid Movsumov 09/09/19
25
$givenday = date("w", mktime(0, 0, 0, MM, dd, yyyy));

Isso fornece o dia da semana da própria data em que 0= domingo e 6= sábado. A partir daí, você pode simplesmente calcular de volta para o dia que desejar.

Yuvalik
fonte
6
Essa resposta retorna se uma determinada data é domingo ou segunda-feira etc. Mas, o questionador solicitou a data do domingo da semana da data especificada, conforme mencionado em seu comentário na pergunta original.
Rakib
19

Esta pergunta precisa de uma boa resposta 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'));

Resultado:-

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

Isso vai lidar com os limites do ano e os anos bissextos.

vascowhite
fonte
18

EDIT: o link abaixo não está mais em execução na versão do PHP declarada. Está sendo executado no PHP 5.6, o que melhora a confiabilidade do strtotime, mas não é perfeito! Os resultados na tabela são resultados ao vivo do PHP 5.6.

Pelo que vale, aqui está um detalhamento do comportamento instável do strtotime ao determinar um quadro de referência consistente:

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

Basicamente, apenas essas seqüências fornecerão a mesma data de maneira confiável, independentemente do dia da semana em que você estiver no momento em que as ligar:

strtotime("next monday");
strtotime("this sunday");
strtotime("last sunday"); 
AgmLauncher
fonte
O artigo também forneceu um código específico para usar: $ start_of_week = strtotime ("próxima segunda-feira - 1 semana"); // retornará segunda-feira da semana atual a partir das 00:00:00 "$ end_of_week = strtotime (" próxima segunda-feira - 1 segundo "); // retornará domingo da semana atual que termina às 23:59:59"
Scott M. Stolz
11

O código a seguir deve funcionar com qualquer data personalizada, apenas usa o formato de data desejado.

$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;

Testei o código com o PHP 5.2.17 Resultados:

Start: 30-07-2012
End: 05-08-2012
Malagana
fonte
1
Vale ressaltar que isso sempre retornará na segunda-feira anterior; portanto, se $ custom_date for segunda-feira, retornará a data da segunda-feira uma semana antes.
precisa saber é o seguinte
2
Não funciona corretamente, hoje é domingo, os resultados são: Início: 09-09-2013 Fim: 22-09-2013
user2019515
10

Assumindo segunda-feira como o primeiro dia da semana, isso funciona:

echo date("M-d-y", strtotime('last monday', strtotime('next week', time())));
shasi kanth
fonte
1
"MM-dd-aaaa" não é o mesmo que "Ymd", adapte sua resposta às especificidades da pergunta.
Yevgeniy Afanasyev
1
date ("MM-dd-aaaa") gera a data como: NovNov-0202-15151515. Espero que deve ser: date ( "MDA") que gera uma data legível como: Nov-02-15
Shasi kanth
"MM-dd-aaaa" vem da pergunta. Se você não tiver certeza do que isso significa - pergunte em um comentário à pergunta. Obrigado por modificar sua resposta.
Yevgeniy Afanasyev
9

Que tal agora?

$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
fonte
8
Na segunda-feira passada, você receberá a segunda-feira anterior.
Ikke
8

É isso que estou usando para obter o primeiro e o último dia da semana a partir de qualquer data . Neste caso, segunda-feira é o primeiro dia da 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');
ThEBiShOp
fonte
1
Essa é a verdadeira resposta!
Manuel
1
Funciona como um encanto!
Liga
6

Aqui estou considerando o domingo como o primeiro e o sábado como o último dia da 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;  

Resultado :

Início: 05-08-2012
Fim: 08-08-2012

Irshad Sheikh
fonte
5

Que tal agora?

$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
fonte
4

Tente o seguinte:

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)));

(a partir deste tópico do fórum )

James Skidmore
fonte
como faço para obter o número da semana e o ano em tudo isso? Eu tenho uma data de seqüência no formato MM-dd-aaaa #
Iggy Ma
4

Esta é a solução mais curta e legível que encontrei:

    <?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);
    ?>

strtotimeé mais rápido que new DateTime()->getTimestamp().

dipser
fonte
Isto é perfeito, ver a minha correção para datas Australian / Reino Unido
zanderwar
4

Apenas use date($format, strtotime($date,' LAST SUNDAY + 1 DAY'));

Kondziutek
fonte
2

A função seguinte da versão pré 5.3 do PHP fornece o primeiro dia da semana de uma determinada data (neste 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
fonte
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"));
user195257
fonte
2
$monday = date('d-m-Y',strtotime('last monday',strtotime('next monday',strtotime($date))));

Você precisa chegar na próxima segunda-feira primeiro e depois na "segunda-feira" da próxima segunda-feira. Portanto, se a data especificada for segunda-feira, ela retornará a mesma data não na semana passada segunda-feira.

Veneno Fedy
fonte
2

Se você deseja segunda-feira como o início de sua semana, faça o seguinte:

$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
fonte
O que torna isso preferível a esta resposta ou a esta resposta ? Parece-me que há mais do que bastante opções nas outras 30 respostas ...
Mogsdad
THX. Esta é uma solução simples e funciona como um encanto.
precisa saber é o seguinte
2

Uma maneira inteligente de fazer isso é permitir que o PHP lide com diferenças de fuso horário e horário de verão (DST). Deixe-me mostrar como fazer isso.

Esta função irá gerar todos os dias de segunda a sexta-feira, inclusive (útil para gerar dias úteis da semana):

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;
}

Isso retornará às vezes de segunda a sexta-feira da semana atual. Para fazer o mesmo em uma data arbitrária, passe uma data como parâmetro para DateTimeUtilities ::getPeriodFromMondayUntilFriday, assim:

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

Interessado apenas na segunda-feira, como o OP pediu?

$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
fonte
1

Você analisa a data usando strptime()e usando date()no resultado:

date('N', strptime('%m-%d-%g', $dateString));
soulmerge
fonte
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 e aaaa na pergunta não são sintaxe de formato de data php padrão - não sei ao certo o que significa, então defino $ start_date com ISO ano-mês-dia)

micahwittman
fonte
1

Outra maneira de fazer isso ....

$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
fonte
1

A maneira mais fácil de obter o primeiro dia (segunda-feira) da semana atual é:

strtotime("next Monday") - 604800;

onde 604800 - é a contagem de segundos em 1 semana (60 * 60 * 24 * 7).

Este código é exibido na próxima segunda-feira e diminui por 1 semana. Esse código funcionará bem em qualquer dia da semana. Mesmo que hoje seja segunda-feira.

Anton Popov
fonte
1

Achei isso bastante frustrante, considerando que meu fuso horário é australiano e que strtotime() odeia datas no Reino Unido.

Se o dia atual for um domingo, strtotime("monday this week")retornará no dia seguinte.

Para superar isso:

Cuidado : Isso é válido apenas para datas da Austrália / 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
fonte
2
Isso funciona para datas nos EUA também. Eu testei isso com o fuso horário de Newyork.
precisa
Enquanto o domingo não for seu primeiro dia da semana (segunda-feira na Austrália / Reino Unido), tudo ficará bem.
Zanderwar
1

Aqui está um exemplo para o primeiro dia da semana passada e o último dia da semana passada como um 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
fonte
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
fonte
Útil quando temos segunda-feira como o primeiro dia da semana (seg-dom).
Kamran Mushtaq
0

Eu me deparei com essa questão algumas vezes e sempre surpreendi que as funções de data não tornem isso mais fácil ou mais claro. Aqui está minha solução para PHP5 que usa a DateTimeclasse:

/**
 * @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;
}

É necessário clonar para evitar alterar a data original.

contrebis
fonte
0

A respeito:

$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>';

Não é a melhor maneira, mas eu testei e, se eu estiver nesta semana, recebo a segunda-feira correta, e se estiver em uma segunda-feira, receberei essa segunda-feira.

CoffeJunky
fonte