Получение первого дня недели в месяц с strtotime

Я пытаюсь выяснить первую среду месяца, используя strtotime, но аргумент "первый средой" не срабатывает всякий раз, когда первая среда выпадает на 1-й.

Для более общей иллюстрации этой проблемы см. следующий код и результат:

$mon = strtotime("December 2010 first monday");
$tue = strtotime("December 2010 first tuesday");
$wed = strtotime("December 2010 first wednesday");
$thu = strtotime("December 2010 first thursday");
$fri = strtotime("December 2010 first friday");
$sat = strtotime("December 2010 first saturday");
$sun = strtotime("December 2010 first sunday");

echo strftime("%m/%d/%y", $mon) . "<br>";
echo strftime("%m/%d/%y", $tue) . "<br>";
echo strftime("%m/%d/%y", $wed) . "<br>";
echo strftime("%m/%d/%y", $thu) . "<br>";
echo strftime("%m/%d/%y", $fri) . "<br>";
echo strftime("%m/%d/%y", $sat) . "<br>";
echo strftime("%m/%d/%y", $sun) . "<br>";

Результаты в:

12/06/10
12/07/10
12/08/10
12/02/10
12/03/10
12/04/10
12/05/10

Заметьте что-нибудь? Разве один день недели не должен совпадать с 1-м месяцем? Но это никогда не происходит, и вместо этого второй экземпляр дня, 8-го, всегда возвращается.

У кого-нибудь есть объяснение?

Ответ 1

У меня нет никаких объяснений, так как я тоже ослеплен, но мне удалось выяснить, как вы получаете правильную дату, опустив "первый", например:

$ php -r 'echo date("m/d/y", strtotime("December 2010 Wednesday"));'
12/01/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Thursday"));'
12/02/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Friday"));'
12/03/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Saturday"));'
12/04/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Sunday"));'
12/05/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Monday"));'
12/06/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Tuesday"));'
12/07/10

Ответ 2

Исходя из предоставленных ответов, нужно знать различия в относительном форматировании даты между php 5.2 и php 5.3.

TEST:

$date1 = strtotime("first wednesday of 2010-12");
$date2 = strtotime("first wednesday 2010-12");
$date3 = strtotime("wednesday 2010-12");

5.2 Результаты:

1969-12-31
2010-12-08
2010-12-01

5.3 Результаты:

2010-12-01
2010-12-08
2010-12-01

Поэтому только третий метод возвращает правильные результаты в версиях PHP 5.

Ответ 3

Это неправильное форматирование. Вам нужно включить of:

echo strftime("%m/%d/%y", strtotime("first Monday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Tuesday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Wednesday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Thursday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Friday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Saturday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Sunday of December 2010"));

Печать

12/06/10
12/07/10
12/01/10
12/02/10
12/03/10
12/04/10
12/05/10

Принятое решение работает, но вы столкнулись с проблемами, если хотите найти второй рабочий день:

echo strftime("%m/%d/%y", strtotime("December 2010 second Wednesday"));

Печать

12/15/10

В документах есть несколько примеров:

http://www.php.net/manual/en/datetime.formats.relative.php

Второй блок заметок в приведенной выше документации объясняет, как of влияет на процесс расчета даты:

Также обратите внимание, что "из" в "порядковом space dayname space 'of'" и "last" space dayname space 'of' "делает что-то особенное.

  • Он устанавливает день месяца в 1.
  • " порядковый номер дня 'из' 'не переходит к другому дню. (Пример: "первый вторник июля 2008 года" означает "2008-07-01" ).
  • "ordinal dayname" продвигается к другому дню. (Пример: "сначала вторник, июль 2008 года" означает "2008-07-08", см. также пункт 4 в списке выше).
  • "'last' dayname 'of'" принимает последнее имя дня текущего месяца. (Пример: "последний wed июля 2008 года" означает "2008-07-30" )
  • "'last' dayname" берет последнее имя дня с текущего дня. (Пример: "последний июль 2008" означает "2008-06-25"; "июль 2008" первые комплекты текущую дату до "2008-07-01" и то "последний wed" переходит к предыдущему Среда, которая является "2008-06-25" ).

Ответ 4

Я нашел это примечание в руководстве по PHP.

"В PHP 5 до 5.2.7 запрос на заданное вхождение данного дня недели в месяц, когда этот день недели был первым днем ​​месяца, неправильно добавит одну неделю к возвращенной метке времени. Это было исправлено в 5.2.7 и более поздние версии."

Ответ 5

PHP 5.5.11

$firstWeekdayOfMonth = new DateTime('first weekday 0 jun 2016');

Я не знаю, почему, но нулевой вид силы, чтобы strtotime parser начинался в начале месяца с первого дня.