Получение первого дня недели в месяце с помощью strtotime - PullRequest
11 голосов
/ 05 декабря 2010

Я пытаюсь вычислить первую среду данного месяца, используя 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

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

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

Ответы [ 5 ]

10 голосов
/ 07 декабря 2010

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

ТЕСТ:

$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.

8 голосов
/ 05 декабря 2010

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

$ 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
5 голосов
/ 05 декабря 2010

Это просто ваше форматирование, которое является неправильным.Вам необходимо указать 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 влияет на процесс вычисления даты:

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

  1. Устанавливает день месяца равным 1.
  2. "порядковый номер дня" в "не переходит в другой день".(Пример: «первый вторник июля 2008 года» означает «2008-07-01»).
  3. «порядковый день» переходит на другой день.(Пример: «первый вторник июля 2008» означает «2008-07-08», см. Также пункт 4 в приведенном выше списке).
  4. «last 'dayname' of '" принимает последнее имя текущего днямесяц.(Пример: «последний день июля 2008 года» означает «2008-07-30»)
  5. «Последнее имя дня» берет последнее имя дня текущего дня.(Пример: «последнее полугодие 2008 года» означает «2008-06-25»; «июль 2008» сначала устанавливает текущую дату на «2008-07-01», а затем «последнее полугодие» перемещается в предыдущую среду, которая называется «2008»).-06-25 ").
1 голос
/ 08 марта 2011

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

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

0 голосов
/ 25 августа 2016

PHP 5.5.11

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

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

...