web-dev-qa-db-fra.com

Obtenir les jours de début et de fin d'une semaine donnée dans PHP

J'essaie d'obtenir la plage de semaines en utilisant dimanche comme date de début et une date de référence, telle que $date, mais je n'arrive pas à comprendre.

Par exemple, si j'avais $ date du 2009-05-01, j'aurais les 2009-04-26 et 2009-05-02. 2009-05-10 donnerait 2009-05-10 et 2009-05-16. Mon code actuel ressemble à ceci (je ne me souviens plus d'où je l'ai soulevé, car j'ai oublié de noter l'URL dans mes commentaires):

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

J'ai réalisé que tout ce que cela faisait était d'ajouter 7 jours à la date actuelle. Comment ferais-tu ceci?

29
Zahymaka

Je voudrais profiter de PHP strtotime awesomeness:

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

Testé sur les données que vous avez fournies et cela fonctionne. Je n'aime pas particulièrement toute la référence que vous avez, cependant. Si telle était ma fonction, je l'aurais comme ceci:

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

Et appelez ça comme ça:

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

Je ne suis pas un grand partisan des mathématiques pour des choses comme celle-là. Les dates sont délicates et je préfère que PHP le découvre.

83
Paolo Bergantino

Pour tous ceux qui utilisent encore mktime (), strtotime () et d'autres fonctions PHP ..., essayez PHP5 DateTime Class. J'étais hésitant au début, mais c'est vraiment facile à utiliser. N'oubliez pas d'utiliser clone () pour copier vos objets.

Modifier: Ce code a été récemment modifié pour traiter le cas où le jour actuel est le dimanche. Dans ce cas, nous devons avoir le samedi passé et ensuite ajouter un jour pour avoir le dimanche.

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

Puis formatez comme vous en avez besoin.

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

Assurez-vous de définir votre fuseau horaire tôt dans votre code.

date_default_timezone_set('America/New_York');
20
jjwdesign

Apparemment, la valeur de formatage de date () ou la méthode de formatage d'un objet DateTime renverront le jour de la semaine sous forme de nombre (par défaut, 0 = dimanche, 1 = lundi, etc.)

Vous pouvez prendre ceci et soustraire sa valeur en jours au jour actuel pour trouver le début de la semaine.

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

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

$ start_date sera désormais égal au dimanche de cette semaine, à partir de là, vous pourrez ajouter 7 jours pour obtenir la fin de la semaine ou ce que vous avez.

9
Crazy Joe Malloy

Sur la base de la réponse de @ jjwdesign, j'ai développé une fonction permettant de calculer le début et la fin d'une semaine pour une date donnée à l'aide de la classe DateTime. FONCTIONNE SUR PHP 5.3.0 ++

La différence est que vous pouvez définir le jour de votre choix comme "début" entre 0 (lundi) et 6 (dimanche).

Voici la fonction:

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

Résultats :

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
)
4
David Bélanger
3
Iiridayn

Voici ma version, qui utilise une notion similaire à celle de 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 );
}

Légèrement testé. Le code peut ne pas être à l'épreuve des balles ou traiter des dates lointaines ou futures. À utiliser à vos risques et périls. Ne plongez pas le code dans l'eau. Ne montrez pas le code à ceux qui sont nerveux ou qui détestent le signe dollar. Non testé sur les animaux. Sans danger pour les végétariens. L'auteur garantit que le code ne vous parlera jamais. Dans le cas peu probable où le code tenterait de vous engager dans une conversation, l'auteur vous conseille de ne pas tenir compte de tous les conseils qu'il donne.

2
Rob

Utilisez ceci pour obtenir le numéro "semaine" à partir d’une date donnée.

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

Passez maintenant les paramètres pour la fonction getWeekDates comme "année (2009)" et "$ semaine".

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

Pour plus d'informations, consultez ce lien http://blog.ekini.net/2009/07/09/php-get-start-and -end-dates-of-a-week-from-datew/

1
Vinit Kadkol

Vous pouvez maintenant utiliser DateTime pour obtenir les dates de début/fin de semaine (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")];
}

Utilisation

print_r( getDateRangeForWeek("2016-05-07") );

print_r( getDateRangeForAllWeeks("2015-11-07", "2016-02-15") );
1
Waqas

Pour être honnête, j'ai du mal à comprendre le code que vous avez posté;)

Je suppose que quelque chose comme ceci devrait faire l'affaire:

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
rodion

Sans autant de manipulation de chaîne, vous pouvez effectuer quelques calculs simples sur les horodatages. 

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

Basé sur la version de David Bélanger (malheureusement, mon représentant ne me permettra pas de poster un commentaire en réaction à son post ..). 

Lorsque la date d'entrée est lundi et que le premier jour de la semaine est défini sur lundi, la version d'origine est renvoyée la semaine précédente, mais n'est pas à jour. Voici le petit correctif (avec le reste de la fonction orig.):

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