Получение первого дня недели в месяц с 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 начинался в начале месяца с первого дня.