PHP получает начальную и конечную дату недели по номеру недели - PullRequest
46 голосов
/ 01 февраля 2011

Я видел несколько вариантов по этому вопросу, но я думаю, что на этот вопрос пока нет ответа.

Мне нужно получить дату начала и окончания недели, выбранные по году и номеру недели (не по дате)

* * 1004 пример: * * 1005

ввод:

getStartAndEndDate($week, $year);

выход: * +1010 *

$return[0] = $firstDay;
$return[1] = $lastDay;

Возвращаемым значением будет что-то вроде массива, в котором первая запись является датой начала недели, а вторая - датой окончания.

ДОПОЛНИТЕЛЬНО: пока мы на нем, формат даты должен быть Y-n-j (обычный формат даты, без начальных нулей.

Я пытался редактировать существующие функции, которые почти делали то, что я хотел, но мне пока не повезло.

Пожалуйста, помогите мне, спасибо заранее.

Ответы [ 14 ]

147 голосов
/ 17 декабря 2013

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

function getStartAndEndDate($week, $year) {
  $dto = new DateTime();
  $dto->setISODate($year, $week);
  $ret['week_start'] = $dto->format('Y-m-d');
  $dto->modify('+6 days');
  $ret['week_end'] = $dto->format('Y-m-d');
  return $ret;
}

$week_array = getStartAndEndDate(52,2013);
print_r($week_array);

Возвращает:

Array
(
    [week_start] => 2013-12-23
    [week_end] => 2013-12-29
)

Объяснено:

  • Создать новый объект DateTime, которыйпо умолчанию now ()
  • Вызовите setISODate, чтобы изменить объект на первый день $ недели $ года вместо now ()
  • Форматировать дату как 'Ymd' и вставить в $ ret ['week_start']
  • Измените объект, добавив 6 дней, что будет концом $ week
  • Отформатируйте дату как' Ymd 'и вставьте в $ ret [' week_end ']

Более короткая версия (работает в> = php5.3):

function getStartAndEndDate($week, $year) {
  $dto = new DateTime();
  $ret['week_start'] = $dto->setISODate($year, $week)->format('Y-m-d');
  $ret['week_end'] = $dto->modify('+6 days')->format('Y-m-d');
  return $ret;
}

Может быть сокращена с помощью доступа к члену класса при создании экземпляра in> = php5.4.

40 голосов
/ 01 февраля 2011

Много лет назад я нашел эту функцию:

function getStartAndEndDate($week, $year) {
  $dto = new DateTime();
  $dto->setISODate($year, $week);
  $ret['week_start'] = $dto->format('Y-m-d');
  $dto->modify('+6 days');
  $ret['week_end'] = $dto->format('Y-m-d');
  return $ret;
}

$week_array = getStartAndEndDate(52,2013);
print_r($week_array);
13 голосов
/ 21 апреля 2016

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

function getStartAndEndDate($year, $week)
{
   return [
      (new DateTime())->setISODate($year, $week)->format('Y-m-d'), //start date
      (new DateTime())->setISODate($year, $week, 7)->format('Y-m-d') //end date
   ];
}

Функция setISODate() принимает три аргумента: $year, $week и $day соответственно, где $day по умолчанию равно 1 - первый день недели.Поэтому мы передаем 7, чтобы получить точную дату 7-го числа $week.

10 голосов
/ 21 января 2013

Слегка аккуратное решение с использованием формата strtotime "[year] W [week] [day]":

function getStartAndEndDate($week, $year) {
  // Adding leading zeros for weeks 1 - 9.
  $date_string = $year . 'W' . sprintf('%02d', $week);
  $return[0] = date('Y-n-j', strtotime($date_string));
  $return[1] = date('Y-n-j', strtotime($date_string . '7'));
  return $return;
}
3 голосов
/ 05 июля 2015

кратчайший способ сделать это:

function week_date($week, $year){
    $date = new DateTime();
    return "first day of the week is ".$date->setISODate($year, $week, "1")->format('Y-m-d')
    ."and last day of the week is ".$date->setISODate($year, $week, "7")->format('Y-m-d'); 
}
echo week_date(12,2014);
2 голосов
/ 05 марта 2019

Вы можете получить конкретный день недели с указанной ниже даты, как я получаю первый и последний день

$date = date_create();

// get the first day of the week
date_isodate_set($date, 2019, 1);

    //convert date format and show     
    echo date_format($date, 'Y-m-d') . "\n";

// get the last date of the week
date_isodate_set($date, 2019, 1, 7);

     //convert date format and show        
     echo date_format($date, 'Y-m-d') . "\n";

Вывод =>

2018-12-31

2019-01-06

2 голосов
/ 06 мая 2015

Это старый вопрос, но многие из представленных выше ответов кажутся неверными.Я придумал собственное решение:

function getStartAndEndDate($week, $year){
    $dates[0] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT)));
    $dates[1] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT).' +6 days'));
    return $dates;
}
1 голос
/ 28 июня 2018

Для документации (поскольку Google занимает этот вопрос первым при поиске «php datetime start end this week»).

Если вам нужны начальная дата и конечная дата для текущей недели (сDateTime):

$dateTime = new DateTime('now');
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
$sunday = clone $dateTime->modify('Sunday this week');

var_dump($monday->format('Y-m-d')); // e.g. 2018-06-25
var_dump($sunday->format('Y-m-d')); // e.g. 2018-07-01

Надеюсь, это поможет.

1 голос
/ 07 февраля 2015

Расчет Рохама Рафии неверен. Вот краткое решение:

// week number to timestamp (first day of week number)
function wn2ts($week, $year) {
    return strtotime(sprintf('%dW%02d', $year, $week));
}

если вы хотите, чтобы последний день недели был номером, вы можете добавить 6 * 24 * 3600

1 голос
/ 01 февраля 2011

Сначала нам нужен день с этой недели, поэтому, зная номер недели и зная, что у недели есть семь дней, мы собираемся сделать так, чтобы

$pickADay = ($weekNo-1) * 7 + 3;

таким образом, pickAday был бы днем ​​в нашемжелаемая неделя.

Теперь, когда мы знаем год, мы можем проверить, какой это день.все просто, если нам нужны только даты, более новые, чем отметка времени unix. Мы получим отметку времени unix для первого дня года и добавим к ней 24*3600*$pickADay, и все просто отсюда, потому что у нас есть отметка времени, мы можем знать, какой деньэто неделя и вычислим соответственно голову и хвост этой недели.

Если мы хотим узнать то же самое, скажем, о 12-й неделе 1848 года, мы должны использовать другой подход, поскольку мы не можем получить метку времени.Зная, что каждый год в день увеличивается на 1 значение дня недели (1 ноября прошлого года было в воскресенье, этот год - в понедельник, за исключением високосных лет, когда он продвигается на 2 дня, я полагаю, вы можете это проверить).Что бы я сделал, если бы год был старше 1970 года, чем разница между ним и необходимым годом, чтобы узнать, сколько там лет, подсчитать день недели, так как мой pickADay был частью 1970 года, перенести его обратно на один день недели для каждого,$shiftTimes = ($yearDifference + $numberOfLeapYears)%7, в разнице.сдвиньте день назад на $ shiftTimes, тогда вы узнаете, какой день недели был в тот день в те годы назад, а затем найдите выходной и недельный хвост.То же самое можно использовать и в будущем, если это кажется проще.Попробуйте, если это работает, и скажите мне, если это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...