Otrzymasz pierwszy dzień tygodnia w PHP?


124

Biorąc pod uwagę MM-dd-yyyyformat daty , czy ktoś może mi pomóc w wyznaczeniu pierwszego dnia tygodnia?


4
Co masz na myśli mówiąc o pierwszym dniu tygodnia? Masz na myśli Sun, Mon? Czy masz na myśli datę pierwszego dnia tygodnia?
Jeffrey Hines

2
Pierwszy dzień tygodnia jest stały: jest poniedziałek (ewentualnie niedziela). Czy chodzi o to, że chcesz uzyskać datę poniedziałku poprzedzającego daną dowolną datę?
Jon Cram

Jaka wersja PHP - 4 czy 5?
Jon Cram

data niedzieli tygodnia. php 5
Iggy Ma

Dziwne, on prosi o DateTimerozwiązanie i większość odpowiedzi go nie dostarcza. =)
lin

Odpowiedzi:


143

Oto, czego używam ...

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

$ dzień zawiera liczbę od 0 do 6 reprezentującą dzień tygodnia (niedziela = 0, poniedziałek = 1 itd.).
$ week_start zawiera datę niedzieli bieżącego tygodnia w formacie mm-dd-rrrr.
$ week_end zawiera datę soboty bieżącego tygodnia w formacie mm-dd-rrrr.


1
ale to oznacza początek i koniec „tego tygodnia”, prawda?
Oki Erie Rinaldi

co jeśli podany zostanie numer tygodnia? i chcę, aby zwracała datę początkową i końcową tego tygodnia.
Oki Erie Rinaldi

1
@OkiErieRinaldi Prawdopodobnie powinieneś otworzyć nowe pytanie, aby otrzymać należytą uwagę.
JadedCore

Nie martw się, mam to @JadedCore!
Oki Erie Rinaldi,

Nie jestem pewien, dlaczego ten drugi jest wyższy. To nie działa, ale ten działa! 3v4l.org/q6kKY
Jason

67
strtotime('this week', time());

Zastąp czas (). Metody na następną niedzielę / ostatni poniedziałek nie będą działać, jeśli bieżącym dniem jest niedziela / poniedziałek.


55
$monday = strtotime('last monday', strtotime('tomorrow'));
Lewis Buckley

this weeknie działa, jeśli musisz mieć zawsze poprzedni początek tygodnia, ale komentarz @ LewisBuckley to robi.
Smar

Drugi argument time()to opcja, jeśli chcesz określić dzisiaj.
Ifnot

u mnie nie zadziałało, musiałem ustawić nieco inną składnię dla YTD, MTD, WTD.
Ron,

6
Ta odpowiedź daje niespójne wyniki, w zależności od używanej wersji PHP: 3v4l.org/Z3k4E @ LewisBuckley Rozwiązanie jest spójne dla wszystkich wersji: 3v4l.org/Eeh9c
Chris Baker

62

Bardzo prosta w obsłudze strtotimefunkcja :

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

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

Trochę różni się w zależności od wersji PHP :

Wyjście dla 5.3.0 - 5.6.6, php7 @ 20140507 - 20150301, hhvm-3.3.1 - 3.5.1

2015-03-16
2015-03-22

Wyjście dla 4.3.5 - 5.2.17

2015-03-23
2015-03-22

Wyjście dla 4.3.0 - 4.3.4

2015-03-30
2015-03-29

Porównanie z Edge-Cases

Względne opisy, takie jak ten tydzień, mają swój własny kontekst. Poniżej przedstawiono dane wyjściowe dla poniedziałku i niedzieli w tym tygodniu, kiedy jest poniedziałek lub niedziela:

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

Jednak różni się nieco w wersjach PHP :

Wyjście dla 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

Wyjście dla 4.3.5 - 5.0.5, 5.2.0 - 5.2.17

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

Wyjście dla 5.1.0 - 5.1.6

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

Wyjście dla 4.3.0 - 4.3.4

2015-03-23
2015-03-29
2015-03-30
2015-03-29

dlaczego to nie działa na datę 2016-06-05, podaje daty następnych tygodni.

1
Dzięki za to, właśnie zmodyfikowałem ten kod, aby móc przekazać opcjonalny parametr daty $ dt = $ custom_date? strtotime ($ custom_date): time (); $ poniedziałek = data ("Ymd", strtotime ('poniedziałek tego tygodnia', $ dt)); $ sunday = date ("Ymd", strtotime ('niedziela tego tygodnia', $ dt));
Ron Michael

47

Nie komplikuj :

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

Źródło: podręcznik PHP

Uwaga: jak zauważył jakiś użytkownik, wartość $ dateTime zostanie zmodyfikowana.


edycja: literówka lub nieznana składnia? skąd pochodzi \? $dateTime = new \DateTime('2012-05-14');
Sliq

2
Robię to, aby uniknąć konfliktu z możliwym automatycznie ładowanym obiektem twojej aplikacji. To jak ścieżka bezwzględna lub ścieżka względna.
job3dot5

9
@Panique - „nieznana składnia” to składnia przestrzeni nazw PHP 5.3. Przestrzenie nazw umożliwiają poprzedzanie klasy przestrzenią nazw, po której następuje ukośnik odwrotny. Tutaj używa go bez przestrzeni nazw, aby określić DateTimeklasę podstawową , co oznacza, że ​​kod będzie działał, nawet jeśli masz inną klasę wywołaną DateTimew bieżącej przestrzeni nazw.
Spudley

Czy nazwa dnia jest zawsze w języku angielskim?
Marwelln

1
Część klonowana nie działa poprawnie. Powinieneś najpierw sklonować, a następnie wykonać operację na klonie, jeśli potrzebujesz oryginalnego.
Farid Movsumov

25
$givenday = date("w", mktime(0, 0, 0, MM, dd, yyyy));

To daje ci dzień tygodnia podanej daty, gdzie 0= niedziela i 6= sobota. Stamtąd możesz po prostu obliczyć wstecz do żądanego dnia.


6
Ta odpowiedź zwraca, czy dana data to niedziela, czy poniedziałek itp. Jednak pytający zapytał o datę niedzieli tygodnia z podanej daty, jak wspomniano w komentarzu do pierwotnego pytania.
Rakib

19

To pytanie wymaga dobrej odpowiedzi 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'));

Wynik:-

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

Dotyczy to granic lat i lat przestępnych.


18

EDYTUJ: poniższe łącze nie działa już w podanej wersji PHP. Działa na PHP 5.6, co poprawia niezawodność strtotime, ale nie jest idealne! Wyniki w tabeli są wynikami na żywo z PHP 5.6.

Co jest warte, oto rozbicie dziwacznego zachowania strtotime podczas określania spójnego układu odniesienia:

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

Zasadniczo tylko te ciągi niezawodnie podają tę samą datę, niezależnie od dnia tygodnia, w którym aktualnie się do nich dzwonisz:

strtotime("next monday");
strtotime("this sunday");
strtotime("last sunday"); 

W artykule podano również kod do użycia: $ start_of_week = strtotime ("następny poniedziałek - 1 tydzień"); // Zwróci poniedziałek bieżącego tygodnia zaczynający się o 00:00:00 "$ end_of_week = strtotime (" następny poniedziałek - 1 sekunda "); // Zwróci niedzielę bieżącego tygodnia kończącą się o 23:59:59"
Scott M. Stolz

11

Poniższy kod powinien działać z dowolną niestandardową datą, po prostu używa żądanego formatu daty.

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

Przetestowałem kod w PHP 5.2.17 Wyniki:

Start: 30-07-2012
End: 05-08-2012

1
Warto zauważyć, że zawsze zwróci to poprzedni poniedziałek, więc jeśli $ custom_date to poniedziałek, zwróci datę poniedziałku tydzień wcześniej.
Hill79

2
Nie działa poprawnie, dziś jest niedziela, wyniki to: Początek: 09-09-2013 Koniec: 22-09-2013
user2019515

10

Zakładając, że poniedziałek jest pierwszym dniem tygodnia, działa to:

echo date("M-d-y", strtotime('last monday', strtotime('next week', time())));

1
„MM-dd-yyyy” to nie to samo, co „Ymd”, dostosuj odpowiedź do specyfiki pytania.
Yevgeniy Afanasyev

1
date („MM-dd-yyyy”) wyświetla datę jako: NovNov-0202-15151515. Mam nadzieję, że powinno to być: data („Mdy”), która wyświetla czytelną datę, na przykład: 02-15 listopada
shasi kanth

Z pytania pochodzi „MM-dd-yyyy”. Jeśli nie jesteś pewien, co to znaczy - zapytaj w komentarzu do pytania. Dziękuję za zmianę odpowiedzi.
Yevgeniy Afanasjew

9

Co powiesz na to?

$first_day_of_week = date('m-d-Y', strtotime('Last Monday', time()));
$last_day_of_week = date('m-d-Y', strtotime('Next Sunday', time()));

8
Ostatni poniedziałek w poniedziałek da ci poprzedni poniedziałek.
Ikke

8

Właśnie tego używam, aby uzyskać pierwszy i ostatni dzień tygodnia z dowolnej daty . W tym przypadku poniedziałek to pierwszy dzień tygodnia ...

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

1
To prawdziwa odpowiedź!
Manuel

1
Działa jak marzenie!
Liga

6

Tutaj uważam niedzielę za pierwszy, a sobotę za ostatni dzień tygodnia.

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

Wynik :

Początek: 05-08-2012
Koniec: 11-08-2012


5

Co powiesz na to?

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

4

Spróbuj tego:

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

(z tego wątku na forum )


jak uzyskać w tym wszystkim numer tygodnia i rok? Mam datę w postaci łańcucha w formacie MM-dd-rrrr
Iggy Ma

4

To najkrótsze i najbardziej czytelne rozwiązanie, jakie znalazłem:

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

strtotimejest szybszy niż new DateTime()->getTimestamp().


To jest idealne, zobacz moją poprawkę na daty z Australii / Wielkiej Brytanii
zanderwar


2

Dla wersji PHP przed 5.3 poniższa funkcja podaje pierwszy dzień tygodnia o podanej dacie (w tym przypadku - niedziela, 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")).'
');
?>

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

2
$monday = date('d-m-Y',strtotime('last monday',strtotime('next monday',strtotime($date))));

Najpierw musisz dostać następny poniedziałek, a następnie „ostatni poniedziałek” następnego poniedziałku. Więc jeśli podana data to poniedziałek, zwróci tę samą datę, ale nie w poniedziałek w zeszłym tygodniu.


2

Jeśli chcesz, aby poniedziałek był początkiem tygodnia, zrób to:

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

Co sprawia, że ​​jest to lepsze od tej lub tej odpowiedzi ? Wydaje mi się, że w 30 innych odpowiedziach jest więcej niż wystarczająco opcji ...
Mogsdad

Dzięki. to jest proste rozwiązanie i działa jak urok.
Oleg Popov

2

Sprytnym sposobem na zrobienie tego jest umożliwienie PHP obsługi różnic w strefach czasowych i czasu letniego (DST). Pokażę ci, jak to zrobić.

Ta funkcja wygeneruje wszystkie dni od poniedziałku do piątku włącznie (przydatne do generowania dni roboczych):

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

Spowoduje to wyświetlenie dat od poniedziałku do piątku w bieżącym tygodniu. Aby zrobić to samo dla dowolnej daty, przekaż datę jako parametr do DateTimeUtilities ::getPeriodFromMondayUntilFriday, w ten sposób:

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

Zainteresowany tylko poniedziałkiem, jak pytał PO?

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


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

?>

(Uwaga: MM, dd i rrrr w pytaniu nie są standardową składnią formatu daty php - nie jestem pewien, o co chodzi, więc ustawiłem $ start_date z ISO rok-miesiąc-dzień)


1

Inny sposób na zrobienie tego ....

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

1

Najłatwiejszym sposobem na uzyskanie pierwszego dnia (poniedziałek) bieżącego tygodnia jest:

strtotime("next Monday") - 604800;

gdzie 604800 - to liczba sekund w ciągu 1 tygodnia (60 * 60 * 24 * 7).

Ten kod otrzyma w następny poniedziałek i zmniejszy go na 1 tydzień. Ten kod będzie działał dobrze w każdy dzień tygodnia. Nawet jeśli dzisiaj jest poniedziałek.


1

Uznałem to za dość frustrujące, biorąc pod uwagę, że moja strefa czasowa jest australijska i nie strtotime()znosi dat w Wielkiej Brytanii.

Jeśli bieżącym dniem jest niedziela, strtotime("monday this week")nastąpi powrót następnego dnia.

Aby temu zaradzić:

Uwaga : dotyczy to tylko dat w Australii / Wielkiej Brytanii

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

2
Działa to również w przypadku dat w USA. Przetestowałem to w strefie czasowej Newyork.
Jayesh D

Dopóki niedziela nie jest pierwszym dniem tygodnia (poniedziałek w Australii / Wielkiej Brytanii), będzie dobrze.
zanderwar

1

Oto jedna linijka na pierwszy dzień zeszłego tygodnia i ostatni dzień ostatniego tygodnia jako DateTimeobiekt.

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

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

Przydatne, gdy mamy poniedziałek jako pierwszy dzień tygodnia (pon.-niedz.).
Kamran Mushtaq

0

Kilka razy spotkałem się z tym pytaniem i zawsze byłem zaskoczony, że funkcje daty nie ułatwiają tego ani nie ułatwiają tego. Oto moje rozwiązanie dla PHP5, które używa DateTimeklasy:

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

Konieczne do klonowania, aby uniknąć zmiany pierwotnej daty.


0

Co powiesz na:

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

To nie jest najlepszy sposób, ale przetestowałem i jeśli jestem w tym tygodniu, dostaję właściwy poniedziałek, a jeśli będę w poniedziałek, dostanę ten poniedziałek.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.