Получить первый день недели на PHP?

124

Учитывая MM-dd-yyyyформат даты , может ли кто-нибудь помочь мне получить первый день недели?

Игги Ма
источник
4
Что вы имеете в виду под первым днем ​​недели? Вы имеете в виду вс, пн? Или вы имеете в виду дату первого дня недели?
Джеффри Хайнс,
2
Первый день недели постоянен: это понедельник (или, возможно, воскресенье). Вы имеете в виду, что хотите получить дату понедельника, предшествующего заданной произвольной дате?
Джон Крам,
Какая версия PHP - 4 или 5?
Джон Крам,
дата воскресенья недели. php 5
Игги Ма
Странно, но он просит DateTimeрешения, но в большинстве ответов его не дает. =)
lin

Ответы:

143

Вот что я использую ...

$day = date('w');
$week_start = date('m-d-Y', strtotime('-'.$day.' days'));
$week_end = date('m-d-Y', strtotime('+'.(6-$day).' days'));

$ day содержит число от 0 до 6, представляющее день недели (воскресенье = 0, понедельник = 1 и т. д.).
$ week_start содержит дату воскресенья текущей недели в формате мм-дд-гггг.
$ week_end содержит дату субботы текущей недели в формате мм-дд-гггг.

JadedCore
источник
1
но это означает начало и конец «этой недели», верно?
Оки Эри Ринальди,
что, если указан номер недели? и я хочу, чтобы он возвращал дату начала и окончания этой недели.
Оки Эри Ринальди,
1
@OkiErieRinaldi Вам, вероятно, следует открыть новый вопрос, чтобы получить должное внимание.
JadedCore
Не волнуйтесь, я понял @JadedCore!
Оки Эри Ринальди,
Я не уверен, почему другой выше. Не работает, а вот этот работает! 3v4l.org/q6kKY
Джейсон,
67
strtotime('this week', time());

Заменить время (). Методы "Следующее воскресенье / последний понедельник" не будут работать, если текущий день - воскресенье / понедельник.

laurentb
источник
55
$monday = strtotime('last monday', strtotime('tomorrow'));
Льюис Бакли
this weekне работает, если вам нужно всегда иметь предыдущее начало недели, но комментарий @LewisBuckley делает это.
Smar
Второй аргумент time()необязателен, если вы хотите указать сегодня.
Ifnot 07
у меня не сработало, пришлось использовать немного другой синтаксис для YTD, MTD, WTD.
Рон
6
Этот ответ дает противоречивые результаты в зависимости от используемой версии PHP: решение 3v4l.org/Z3k4E @ LewisBuckley совместимо для всех версий: 3v4l.org/Eeh9c
Крис Бейкер
62

Очень простая в использовании strtotimeфункция :

echo date("Y-m-d", strtotime('monday this week')), "\n";   

echo date("Y-m-d", strtotime('sunday this week')), "\n";

В разных версиях PHP он немного отличается :

Вывод для 5.3.0 - 5.6.6, php7 @ 20140507-20150301, hhvm-3.3.1 - 3.5.1

2015-03-16
2015-03-22

Вывод для 4.3.5 - 5.2.17

2015-03-23
2015-03-22

Вывод для 4.3.0 - 4.3.4

2015-03-30
2015-03-29

Сравнение в крайних случаях

Относительные описания, подобные этой неделе, имеют свой собственный контекст. Ниже показаны выходные данные для понедельника и воскресенья этой недели, когда это понедельник или воскресенье:

$date = '2015-03-16'; // monday
echo date("Y-m-d", strtotime('monday this week', strtotime($date))), "\n";   
echo date("Y-m-d", strtotime('sunday this week', strtotime($date))), "\n";

$date = '2015-03-22'; // sunday
echo date("Y-m-d", strtotime('monday this week', strtotime($date))), "\n";   
echo date("Y-m-d", strtotime('sunday this week', strtotime($date))), "\n";

Кстати, в разных версиях PHP он немного отличается :

Вывод для 5.3.0 - 5.6.6, php7 @ 20140507-20150301, hhvm-3.3.1 - 3.5.1

2015-03-16
2015-03-22
2015-03-23
2015-03-29

Вывод для 4.3.5 - 5.0.5, 5.2.0 - 5.2.17

2015-03-16
2015-03-22
2015-03-23
2015-03-22

Выход для 5.1.0 - 5.1.6

2015-03-23
2015-03-22
2015-03-23
2015-03-29

Вывод для 4.3.0 - 4.3.4

2015-03-23
2015-03-29
2015-03-30
2015-03-29
Раджа Рама Мохан Тавалам
источник
почему это не работает на дату 2016-06-05, это дает даты на следующей неделе.
1
Спасибо за это, я только что изменил этот код, чтобы передать необязательный параметр даты $ dt = $ custom_date? strtotime ($ custom_date): время (); $ monday = date ("Ymd", strtotime ('понедельник на этой неделе', $ dt)); $ sunday = date ("Ymd", strtotime ('воскресенье на этой неделе', $ dt));
Рон Майкл
47

Будь проще :

<?php    
$dateTime = new \DateTime('2020-04-01');
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
$sunday = clone $dateTime->modify('Sunday this week');    
?>

Источник: руководство по PHP.

NB: по мере того, как некоторые пользователи прокомментировали, значение $ dateTime будет изменено.

job3dot5
источник
изменить: опечатка или какой-то неизвестный синтаксис? откуда \? $dateTime = new \DateTime('2012-05-14');
Sliq
2
Я делаю это, чтобы избежать конфликта с возможным автоматически загружаемым объектом вашего приложения. Это похоже на абсолютный или относительный путь.
job3dot5
9
@Panique - «неизвестный синтаксис» - это синтаксис пространства имен PHP 5.3. Пространство имен позволяет вам ставить перед классом пространство имен, за которым следует обратная косая черта. Здесь он использует его без пространства имен, чтобы указать базовый DateTimeкласс, что означает, что код будет работать, даже если у вас есть другой класс, вызванный DateTimeв текущем пространстве имен.
Spudley
Название дня всегда на английском языке?
Marwelln
1
Клонирующая часть работает некорректно. Вы должны сначала клонировать, а затем выполнить операцию с клоном, если вам нужен оригинальный.
Фарид Мовсумов
25
$givenday = date("w", mktime(0, 0, 0, MM, dd, yyyy));

Это дает вам день недели самой данной даты, где 0= воскресенье и 6= суббота. Оттуда вы можете просто рассчитать в обратном направлении к желаемому дню.

Yuvalik
источник
6
Этот ответ показывает, является ли данная дата воскресеньем или понедельником и т. Д. Но спрашивающий спросил дату воскресенья недели данной даты, как указано в его комментарии к исходному вопросу.
Rakib
19

На этот вопрос нужен хороший ответ DateTime : -

function firstDayOfWeek($date)
{
    $day = DateTime::createFromFormat('m-d-Y', $date);
    $day->setISODate((int)$day->format('o'), (int)$day->format('W'), 1);
    return $day->format('m-d-Y');
}

var_dump(firstDayOfWeek('06-13-2013'));

Вывод:-

string '06-10-2013' (length=10)

Это будет иметь дело с границами года и високосными годами.

vascowhite
источник
18

РЕДАКТИРОВАТЬ: приведенная ниже ссылка больше не работает в указанной версии PHP. Он работает на PHP 5.6, что повышает надежность strtotime, но не идеально! Результаты в таблице являются живыми результатами PHP 5.6.

Как бы то ни было, вот анализ шаткого поведения strtotime при определении согласованной системы отсчета:

http://gamereplays.org/reference/strtotime.php

По сути, только эти строки будут надежно указывать вам одну и ту же дату, независимо от того, в какой день недели вы сейчас звоните:

strtotime("next monday");
strtotime("this sunday");
strtotime("last sunday"); 
AgmLauncher
источник
В статье также был указан конкретный код для использования: $ start_of_week = strtotime («следующий понедельник - 1 неделя»); // Вернется понедельник текущей недели, начиная с 00:00:00 "$ end_of_week = strtotime (" следующий понедельник - 1 секунда "); // Вернется воскресенье текущей недели, заканчивающейся в 23:59:59"
Скотт M. Stolz
11

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

$custom_date = strtotime( date('d-m-Y', strtotime('31-07-2012')) ); 
$week_start = date('d-m-Y', strtotime('this week last monday', $custom_date));
$week_end = date('d-m-Y', strtotime('this week next sunday', $custom_date));
echo '<br>Start: '. $week_start;
echo '<br>End: '. $week_end;

Я тестировал код с помощью PHP 5.2.17. Результаты:

Start: 30-07-2012
End: 05-08-2012
Malagana
источник
1
Стоит отметить, что это всегда будет возвращать предыдущий понедельник, поэтому, если $ custom_date - понедельник, он вернет дату понедельника на неделю раньше.
Hill79 05
2
Не работает должным образом, сегодня воскресенье, результаты такие: Начало: 09.09.2013 Конец: 22.09.2013
user2019515
10

Предполагая, что понедельник является первым днем ​​недели, это работает:

echo date("M-d-y", strtotime('last monday', strtotime('next week', time())));
Shasi Kanth
источник
1
«ММ-дд-гггг» - это не то же самое, что «Ymd», пожалуйста, адаптируйте свой ответ с учетом специфики вопроса.
Евгений Афанасьев
1
date ("MM-dd-yyyy") выводит дату как: NovNov-0202-15151515. Я надеюсь, что это должно быть: date ("Mdy"), которая выводит читаемую дату, например: 02-15 ноября
shasi kanth
«ММ-дд-гггг» происходит от вопроса. Если не совсем понимаете, что это значит - задайте в комментарии к вопросу. Спасибо, что изменили свой ответ.
Евгений Афанасьев
9

Как насчет этого?

$first_day_of_week = date('m-d-Y', strtotime('Last Monday', time()));
$last_day_of_week = date('m-d-Y', strtotime('Next Sunday', time()));
birkof
источник
8
Последний понедельник по понедельникам будет означать предыдущий понедельник.
Ikke
8

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

$date = date('Y-m-d') // you can put any date you want
$nbDay = date('N', strtotime($date));
$monday = new DateTime($date);
$sunday = new DateTime($date);
$monday->modify('-'.($nbDay-1).' days');
$sunday->modify('+'.(7-$nbDay).' days');
ThEBiShOp
источник
1
Это настоящий ответ!
Мануэль
1
Работает как шарм!
Лига
6

Здесь я считаю воскресенье первым, а субботу - последним днем ​​недели.

$m = strtotime('06-08-2012');  
$today =   date('l', $m);  
$custom_date = strtotime( date('d-m-Y', $m) );   
if ($today == 'Sunday') {  
   $week_start = date("d-m-Y", $m);  
} else {  
  $week_start = date('d-m-Y', strtotime('this week last sunday', $custom_date));  
}  

if ($today == 'Saturday') {  
  $week_end = date("d-m-Y", $m);
} else {  
  $week_end = date('d-m-Y', strtotime('this week next saturday', $custom_date));  
}
echo '<br>Start: '. $week_start;  
echo '<br>End: '. $week_end;  

Вывод :

Начало: 08.05.2012
Конец: 08.11.2012

Иршад Шейх
источник
5

Как насчет этого?

$day_of_week = date('N', strtotime($string_date));
$week_first_day = date('Y-m-d', strtotime($string_date . " - " . ($day_of_week - 1) . " days"));
$week_last_day = date('Y-m-d', strtotime($string_date . " + " . (7 - $day_of_week) . " days"));
Тарквиний Супербус
источник
4

Попробуй это:

function week_start_date($wk_num, $yr, $first = 1, $format = 'F d, Y')
{
    $wk_ts  = strtotime('+' . $wk_num . ' weeks', strtotime($yr . '0101'));
    $mon_ts = strtotime('-' . date('w', $wk_ts) + $first . ' days', $wk_ts);
    return date($format, $mon_ts);
}

$sStartDate = week_start_date($week_number, $year);
$sEndDate   = date('F d, Y', strtotime('+6 days', strtotime($sStartDate)));

(из этой ветки форума )

Джеймс Скидмор
источник
как мне узнать номер недели и год? У меня строковая дата в формате ММ-дд-гггг
Игги Ма
4

Это самое короткое и удобочитаемое решение, которое я нашел:

    <?php
    $weekstart = strtotime('monday this week');
    $weekstop = strtotime('sunday this week 23:59:59');
    //echo date('d.m.Y H:i:s', $weekstart) .' - '. date('d.m.Y H:i:s', $weekstop);
    ?>

strtotimeбыстрее чем new DateTime()->getTimestamp().

dipser
источник
Это идеально, см. Мое исправление для австралийских / британских дат
zanderwar
4

Просто используйте date($format, strtotime($date,' LAST SUNDAY + 1 DAY'));

Kondziutek
источник
2

Для данной версии PHP до 5.3 следующая функция дает вам первый день недели заданной даты (в данном случае - воскресенье, 03.02.2013):

<?php
  function startOfWeek($aDate){
    $d=strtotime($aDate);
    return strtotime(date('Y-m-d',$d).' - '.date("w",$d).' days');
  }

  echo(date('Y-m-d',startOfWeek("2013-02-07")).'
');
?>
Дэвид Джаши
источник
2
$today_day = date('D'); //Or add your own date
$start_of_week = date('Ymd');
$end_of_week = date('Ymd');

if($today_day != "Mon")
    $start_of_week = date('Ymd', strtotime("last monday"));

if($today_day != "Sun")
                    $end_of_week = date('Ymd', strtotime("next sunday"));
user195257
источник
2
$monday = date('d-m-Y',strtotime('last monday',strtotime('next monday',strtotime($date))));

Сначала вы должны получить следующий понедельник, а затем «последний понедельник» следующего понедельника. Таким образом, если заданная дата - понедельник, она вернет ту же дату, что и понедельник на прошлой неделе.

Феди Веном
источник
2

Если вы хотите начать неделю с понедельника, сделайте следующее:

$date = '2015-10-12';
$day = date('N', strtotime($date));
$week_start = date('Y-m-d', strtotime('-'.($day-1).' days', strtotime($date)));
$week_end = date('Y-m-d', strtotime('+'.(7-$day).' days', strtotime($date)));
Генри Вебер
источник
Что делает этот ответ предпочтительнее этого ответа или этого ответа ? Мне кажется, что в 30 других ответах более чем достаточно вариантов ...
Mogsdad
Спасибо. это простое решение, и оно работает как шарм.
Олег Попов
2

Разумный способ сделать это - позволить PHP обрабатывать разницу в часовых поясах и переход на летнее время (DST). Позвольте мне показать вам, как это сделать.

Эта функция будет генерировать все дни с понедельника по пятницу включительно (удобно для генерации рабочих дней недели):

class DateTimeUtilities {
    public static function getPeriodFromMondayUntilFriday($offset = 'now') {
        $now = new \DateTimeImmutable($offset, new \DateTimeZone('UTC'));
        $today = $now->setTime(0, 0, 1);

        $daysFromMonday = $today->format('N') - 1;

        $monday = $today->sub(new \DateInterval(sprintf('P%dD', $daysFromMonday)));
        $saturday = $monday->add(new \DateInterval('P5D'));

        return new \DatePeriod($monday, new \DateInterval('P1D'), $saturday);
    }
}

foreach (DateTimeUtilities::getPeriodFromMondayUntilFriday() as $day) {
    print $day->format('c');
    print PHP_EOL;
}

Это вернет время с понедельника по пятницу для текущей недели. Чтобы сделать то же самое для произвольной даты, передайте дату в качестве параметра DateTimeUtilities ::getPeriodFromMondayUntilFriday, таким образом:

foreach (DateTimeUtilities::getPeriodFromMondayUntilFriday('2017-01-02T15:05:21+00:00') as $day) {
    print $day->format('c');
    print PHP_EOL;
}

//prints 
//2017-01-02T00:00:01+00:00
//2017-01-03T00:00:01+00:00
//2017-01-04T00:00:01+00:00
//2017-01-05T00:00:01+00:00
//2017-01-06T00:00:01+00:00

Интересует только понедельник, как спрашивал ОП?

$monday = DateTimeUtilities::getPeriodFromMondayUntilFriday('2017-01-02T15:05:21+00:00')->getStartDate()->format('c');
print $monday;
// prints
//2017-01-02T00:00:01+00:00
Нино Шкопац
источник
1

Вы анализируете дату, используя strptime()и используете date()результат:

date('N', strptime('%m-%d-%g', $dateString));
soulmerge
источник
1
<?php
/* PHP 5.3.0 */

date_default_timezone_set('America/Denver'); //Set apprpriate timezone
$start_date = strtotime('2009-12-15'); //Set start date

//Today's date if $start_date is a Sunday, otherwise date of previous Sunday
$today_or_previous_sunday = mktime(0, 0, 0, date('m', $start_date), date('d', $start_date), date('Y', $start_date)) - ((date("w", $start_date) ==0) ? 0 : (86400 * date("w", $start_date)));

//prints 12-13-2009 (month-day-year)
echo date('m-d-Y', $today_or_previous_sunday);

?>

(Примечание: MM, dd и yyyy в вопросе не являются стандартным синтаксисом формата даты php - я не уверен, что имеется в виду, поэтому я установил $ start_date с ISO год-месяц-день)

micahwittman
источник
1

Другой способ сделать это ....

$year = '2014';
$month = '02';
$day = '26';

$date = DateTime::createFromFormat('Y-m-d H:i:s', $year . '-' . $month . '-' . $day . '00:00:00');
$day = date('w', $date->getTimestamp());

// 0=Sunday 6=Saturday
if($day!=0){

   $newdate = $date->getTimestamp() - $day * 86400;  //86400 seconds in a day

   // Look for DST change 
   if($old = date('I', $date->getTimestamp()) != $new = date('I', $newdate)){
       if($old == 0){
           $newdate -= 3600;  //3600 seconds in an hour
       } else {
           $newdate += 3600;
       }
   }

   $date->setTimestamp($newdate);
}

echo $date->format('D Y-m-d H:i:s');
Майкл Павловски
источник
1

Самый простой способ получить первый день (понедельник) текущей недели:

strtotime("next Monday") - 604800;

где 604800 - количество секунд за 1 неделю (60 * 60 * 24 * 7).

Этот код получите в следующий понедельник и уменьшите его на 1 неделю. Этот код будет работать в любой день недели. Даже если сегодня понедельник.

Антон Попов
источник
1

Я нашел это довольно неприятным, учитывая, что мой часовой пояс - австралийский, и я strtotime()ненавижу свидания в Великобритании.

Если текущий день - воскресенье, то strtotime("monday this week")вернется на следующий день.

Чтобы преодолеть это:

Внимание : это действительно только для австралийских / британских дат.

$startOfWeek = (date('l') == 'Monday') ? date('d/m/Y 00:00') : date('d/m/Y', strtotime("last monday 00:00"));
$endOfWeek = (date('l') == 'Sunday') ? date('d/m/Y 23:59:59') : date('d/m/Y', strtotime("sunday 23:59:59"));
zanderwar
источник
2
Это работает и для дат в США. Я тестировал это с часовым поясом Нью-Йорка.
Jayesh D
Если воскресенье - не ваш первый день недели (понедельник в Австралии / Великобритании), все будет в порядке.
zanderwar 01
1

Вот один лайнер для первого дня прошлой недели и последнего дня прошлой недели в виде DateTimeобъекта.

$firstDay = (new \DateTime())->modify(sprintf('-%d day', date('w') + 7))
                             ->setTime(0, 0, 0);
$lastDay = (new \DateTime())->modify(sprintf('-%d day', date('w') + 1))
                            ->setTime(23, 59, 59);
Дэвид Баукум
источник
1
$string_date = '2019-07-31';
echo $day_of_week = date('N', strtotime($string_date));
echo $week_first_day = date('Y-m-d', strtotime($string_date . " - " . ($day_of_week - 1) . " days"));
echo $week_last_day = date('Y-m-d', strtotime($string_date . " + " . (7 - $day_of_week) . " days"));
Сайед Урудж Вакар
источник
Полезно, когда у нас понедельник - первый день недели (пн-вс).
Камран Муштак
0

Я несколько раз сталкивался с этим вопросом и всегда удивлялся, что функции даты не делают его проще или яснее. Вот мое решение для PHP5, использующее этот DateTimeкласс:

/**
 * @param DateTime $date A given date
 * @param int $firstDay 0-6, Sun-Sat respectively
 * @return DateTime
 */
function getFirstDayOfWeek(DateTime $date, $firstDay = 0) {
    $offset = 7 - $firstDay;
    $ret = clone $date;
    $ret->modify(-(($date->format('w') + $offset) % 7) . 'days');
    return $ret;
}

Необходимо клонировать, чтобы не изменить исходную дату.

contrebis
источник
0

Что о:

$date = "2013-03-18"; 
$searchRow = date("d.m.Y", strtotime('last monday',strtotime($date." + 1 day")));
echo "for date " .$date ." we get this monday: " ;echo $searchRow; echo '<br>';

Это не лучший способ, но я тестировал, и если я на этой неделе, я получу правильный понедельник, а если я буду в понедельник, я получу этот понедельник.

CoffeJunky
источник