Подтвердить что ты не робот

PHP получает начальную и конечную дату недели по недельному номеру

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

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

Пример:

ввод:

getStartAndEndDate($week, $year);

выход:

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

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

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

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

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

4b9b3361

Ответ 1

function getStartAndEndDate($week, $year)
{

    $time = strtotime("1 January $year", time());
    $day = date('w', $time);
    $time += ((7*$week)+1-$day)*24*3600;
    $return[0] = date('Y-n-j', $time);
    $time += 6*24*3600;
    $return[1] = date('Y-n-j', $time);
    return $return;
}

Ответ 2

Использование 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 по умолчанию()
  • Вызовите setISODate, чтобы изменить объект на первый день $week of $year вместо now()
  • Введите дату в формате 'Y-m-d' и введите $ret ['week_start']
  • Измените объект, добавив 6 дней, и это будет конец недели $
  • Введите дату в формате 'Y-m-d' и введите $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;
}

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

Ответ 3

Немного более аккуратное решение, используя "[год] W [неделя] [день]" формат strtotime:

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

Ответ 4

Мы можем легко достичь этого без необходимости дополнительных вычислений, кроме тех, которые присущи классу 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.

Ответ 5

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

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

таким образом pickAday будет днем ​​на нашей желаемой неделе.

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

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

Ответ 6

Расчет Roham Rafii ошибочен. Вот короткое решение:

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

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

Ответ 7

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

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

Ответ 9

Даже если вы не хотите использовать определенную дату, вы не сможете избежать этого. Вы можете рассчитать неделю на основе даты ТОЛЬКО.

Шаги:

  • получить первый день года
  • решить, когда начнется первая неделя (есть некоторые правила, которые включают первый четверг, если я помню.
  • добавить несколько недель (ваш первый параметр). Zend_Date имеет функцию add(), где вы можете добавить несколько недель, например. Это даст вам первый день недели.
  • смещение и получение последнего дня.

Я бы рекомендовал работать с последовательными датами, такими как Zend_Date или Груша Дата.

Ответ 10

Самый короткий способ сделать это:

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

Ответ 11

function getStartAndEndDate($week, $year)
    {
        $week_start = new DateTime();
        $week_start->setISODate($year,$week);
        $return[0] = $week_start->format('d-M-Y');
        $time = strtotime($return[0], time());
        $time += 6*24*3600;
        $return[1] = date('d-M-Y', $time);
        return $return;
    }