Получить начало и конец дней для данной недели в PHP - PullRequest
29 голосов
/ 29 мая 2009

Я пытаюсь получить диапазон недели, используя воскресенье в качестве даты начала и контрольную дату, скажем $date, но я просто не могу понять это.

Например, если бы у меня была $ date как 2009-05-01, я бы получил 2009-04-26 и 2009-05-02. 2009-05-10 даст 2009-05-10 и 2009-05-16. Мой текущий код выглядит следующим образом (я не могу вспомнить, откуда я его взял, так как я забыл записать URL в моих комментариях):

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

Я понял, что все, что он сделал, это добавил 7 дней к текущей дате. Как бы вы это сделали?

Ответы [ 14 ]

84 голосов
/ 29 мая 2009

Я хотел бы взять на вооружение 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));
}

Проверено на предоставленных вами данных и работает. Мне не особо нравятся все ссылки, которые у вас есть, хотя. Если бы это была моя функция, я бы так и сделал:

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

И назовите это так:

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

Я не большой поклонник математики для подобных вещей. Даты хитрые, и я предпочитаю, чтобы PHP понял это.

20 голосов
/ 03 июля 2013

Всем, кто все еще использует mktime (), strtotime () и другие функции PHP ... попробуйте класс PHP5 DateTime . Сначала я колебался, но им действительно легко пользоваться. Не забудьте использовать clone () для копирования ваших объектов.

Редактировать: Этот код был недавно отредактирован для обработки случая, когда текущим днем ​​является воскресенье. В этом случае нам нужно узнать прошедшую субботу, а затем добавить один день, чтобы получить воскресенье.

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

Затем отформатируйте, как вам нужно.

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

Удостоверьтесь, что ваш код установлен на ранней стадии вашего кода.

date_default_timezone_set('America/New_York');
9 голосов
/ 29 мая 2009

Очевидно, что форматирование 'w' значения date () или метода форматирования объекта DateTime вернет день недели в виде числа (по умолчанию 0 = воскресенье, 1 = понедельник и т. Д.)

Вы можете взять это и вычесть его значение в днях из текущего дня, чтобы найти начало недели.

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

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

$ start_date теперь будет соответствовать воскресенью той недели, оттуда вы можете добавить 7 дней, чтобы узнать конец недели или что у вас есть.

4 голосов
/ 05 августа 2013

Основываясь на ответе @ jjwdesign, я разработал функцию, которая может вычислять начало и конец недели для конкретной даты, используя класс DateTime. РАБОТАЕТ НА PHP 5.3.0 ++

Разница в том, что вы можете установить желаемый день в качестве «начала» между 0 (понедельник) и 6 (воскресенье).

Вот функция:

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

Результаты:

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
)
3 голосов
/ 04 февраля 2011
2 голосов
/ 29 мая 2009

Вот моя версия, которая использует понятие, аналогичное понятию Клея:

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

Слегка проверено. Код может не быть пуленепробиваемым или обрабатывать даты в далеком прошлом или будущем. Используйте на свой риск. Не погружайте код в воду. Не показывайте код тем, у кого нервный характер или с ненавистью к знаку доллара. Не тестируется на животных. Безопасен для использования вегетарианцами. Автор гарантирует, что код никогда не будет говорить с вами. В том маловероятном случае, если код попытается вовлечь вас в разговор, автор советует вам не обращать внимания ни на какие советы, которые он дает.

1 голос
/ 30 июля 2016

Теперь вы можете использовать DateTime для получения даты начала / окончания недели (ей)

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

Использование

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

print_r( getDateRangeForAllWeeks("2015-11-07", "2016-02-15") );
1 голос
/ 22 августа 2014

Используйте это, чтобы получить номер "недели" от любой данной даты.

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

Теперь передайте параметры функции getWeekDates как "year (2009)" и "$ 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}.";
    }

Для получения дополнительной информации, пожалуйста, обратитесь по этой ссылке http://blog.ekini.net/2009/07/09/php-get-start-and-end-dates-of-a-week-from-datew/

1 голос
/ 27 апреля 2012

Пытаясь найти более упрощенную версию принятого ответа Паоло Бергантино, я нашел действительно хороший способ сделать это:

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

Строка «Воскресенье на этой неделе» всегда означает «Воскресенье в конце этой недели». Если используется метка времени, приходящаяся на воскресенье, это будет следующее воскресенье. Это позволяет избежать необходимости использования троичного оператора в решении Paola.

0 голосов
/ 31 мая 2019

Простой код для возврата дней с начала DateTime и до конца DateTime. Используя метод gmdate (), вы можете форматировать дату / время.

$start_str_date = strtotime($start_date);
$end_str_date = strtotime($end_date);
$interval_days = $end_str_date - $start_str_date;
$days = gmdate('d',$interval_days);
echo $days;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...