2009-05-29 13 views
27

Sto cercando di ottenere l'intervallo settimana utilizzando domenica come data di inizio e una data di riferimento, ad esempio $date, ma non riesco proprio a capirlo.Ottenere inizio e fine giorni per una determinata settimana in PHP

Ad esempio, se avessi $ data come 2009-05-01, riceverei 2009-04-26 e 2009-05-02. Il 2009-05-10 produrrebbe il 2009-05-10 e il 2009-05-16. Il mio codice attuale si presenta così (non mi ricordo dove ho sollevato da, come ho dimenticato di mettere giù l'url nei miei commenti):

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

ho capito tutto quello che ha fatto è stato aggiungere 7 giorni per la corrente Data. come lo faresti?

risposta

81

Vorrei prendere advantange di strtotime suggestione di 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)); 
} 

Testato sui dati che hai fornito e funziona. Non mi piace particolarmente l'intera cosa di riferimento che stai facendo, però. Se questa è stata la mia funzione, avrei che si tratti in questo modo:

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

e chiamarlo in questo modo:

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

Io non sono un grande fan di fare matematica per cose come questa. Le date sono complicate e preferisco che PHP lo capisca.

+2

ho usato il seguente per ottenere l'ultima data di domenica formattata: data ('Ym-d', strtotime ('last_sunday')) –

+3

Dai una prova alla classe DateTime di PHP5! – jjwdesign

+0

@ John M., vedi il mio commento qui sotto su come "domenica scorsa" può essere problematico se oggi è domenica e vuoi __questa settimana. – cdmo

0

Per essere onesto, non ho difficoltà a capire il codice che avete inviato;)

Credo che qualcosa di simile dovrebbe fare il trucco:

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

Senza fare tanta manipolazione delle stringhe, è possibile fare un po ' matematica semplice sul timestamp.

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

Ecco la mia versione, che utilizza un concetto simile a quello di Clay:

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

leggermente testato. Il codice potrebbe non essere a prova di proiettile o gestire le date nel lontano passato o nel futuro. Utilizzare a proprio rischio. Non immergere il codice nell'acqua. Non mostrare il codice a quelli di una disposizione nervosa, o con l'odio del segno del dollaro. Non testato su animali. Sicuro per l'uso da parte dei vegetariani. L'autore garantisce che il codice non ti parlerà mai, mai. Nell'improbabile eventualità che il codice tenti di coinvolgerti in una conversazione, l'autore ti consiglia di ignorare tutti i consigli che fornisce.

8

apparentemente 'w' formattazione valore della data() o il metodo formato di un oggetto DateTime restituirà il giorno della settimana come un numero (per impostazione predefinita, 0 = Domenica, 1 = Lunedi, ecc)

Puoi prendere questo e sottrarre il suo valore come giorni dal giorno corrente per trovare l'inizio della settimana.

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

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

$ start_date sarà ora uguale alla Domenica di quella settimana, da lì è possibile aggiungere 7 giorni per ottenere la fine della settimana o quello che-hanno-te.

+0

lo stesso può essere fatto con la funzione Date: '$ day_della settimana ('w', strtotime ($ start_date))' '$ domenica = data ('Ym-d', strtotime ('-'. $ Day_of_week . 'days', strtotime ($ start_date))) ' –

1

Nel tentativo di trovare una versione più snella della risposta accettata da Paolo Bergantino, ho scoperto davvero un bel modo per ottenere questo fatto:

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

Il 'domenica di questa settimana' stringa significa sempre "La Domenica al fine di questa settimana. " Se utilizzato su un timestamp che cade di domenica, sarà la domenica successiva. Ciò consente di evitare la necessità dell'operatore ternario nella soluzione di Paola.

18

Per tutti coloro che utilizzano ancora mktime(), strtotime() e altre funzioni PHP ... dare una prova alla classe PHP DateTime. All'inizio ero titubante, ma è davvero facile da usare. Non dimenticare di usare clone() per copiare i tuoi oggetti.

Modifica: questo codice è stato modificato di recente per gestire il caso in cui il giorno corrente è domenica. In tal caso, dobbiamo passare lo scorso sabato e aggiungere un giorno per ottenere la domenica.

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

Quindi formattare come necessario.

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

Assicurarsi di impostare il fuso orario in anticipo nel codice.

date_default_timezone_set('America/New_York'); 
+1

A meno che non stia leggendo male, non sono sicuro che questa logica funzionerà se oggi è domenica. Se oggi è domenica e crei un oggetto 'DateTime' dell'ultima domenica, PHP restituirà la domenica precedente, non quella attuale. Pertanto, se la data odierna è il 28/2/2016, il codice sopra riportato riprenderebbe "Questa settimana 21/2/2016 - 2/27/2016" (effettivamente la settimana precedente. Dal lunedì al sabato nasconderebbe questo problema. come '$ dt_min = new DateTime (" ultimo sabato + 24 ore ");' – cdmo

+1

Buona cattura cdmo! Ho cambiato il codice per riflettere. – jjwdesign

3

base alla risposta di @ jjwdesign, ho sviluppato una funzione in grado di calcolare l'inizio e la fine di una settimana per una data specifica utilizzando la classe DateTime. FUNZIONERA SU PHP 5.3.0 ++

La differenza è che è possibile impostare il giorno desiderato come "inizio" tra 0 (lunedì) e 6 (domenica).

Ecco la funzione:

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

Risultati:

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

da 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

Usare questo per ottenere il numero di "settimana" da una certa data.

//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 

Ora passare i parametri per la funzione getWeekDates come "year (2009)" e "$ week".

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

Per maggiori informazioni consultare questo link http://blog.ekini.net/2009/07/09/php-get-start-and-end-dates-of-a-week-from-datew/

0

basato sulla versione di David Bélanger (sfortunatamente, il mio rappresentante. Non mi permette di Invia un commento come reazione al suo posto ..).

Quando la data di inserimento è lunedì e il primo giorno della settimana è impostato come lunedì, la versione originale restituisce la settimana precedente, non corrente. Ecco la piccola correzione (con il resto dell'originaleFunzione):

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

È ora possibile utilizzare DateTime per ottenere date di inizio/fine della settimana (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")); 
Problemi correlati