Допустим, у нас есть следующая проблема: мы должны проверить, является ли дата больше месяца назад или меньше месяца назад. Многие разработчики идут в неправильном направлении, вычисляя текущий месяц, а затем вычитая из него количество месяцев. Конечно, этот подход медленный и полон рисков, позволяющих допускать ошибки. Поскольку за два месяца до января, который является первым месяцем года, фактически ноябрь, который является одиннадцатым месяцем. Из-за этих ловушек этот подход совершенно неверен.
Вопрос в том, может ли PHP помочь нам со встроенными функциями для выполнения этих вычислений за нас. Очевидно, что начиная с версии 5.3.0 и выше, есть раздел ООП, что замечательно, но, к сожалению, эта версия до сих пор не везде обновлена. Итак, как выполнить задачу?
Неправильный подход
Как я уже сказал, есть много способов пойти в неправильном направлении. Одним из них является вычитание 30 дней от текущей даты. Это совершенно неправильно, потому что не каждый месяц имеет 30 дней. Здесь некоторые разработчики начнут задавать массивы для указания количества дней в каждом месяце, которые затем будут использоваться в их сложных вычислениях. Вот пример этого неправильного подхода.
echo date('Y-m-d', strtotime(date('Y-m-d')) - 60*60*24*30);
Эта строка полна ошибок. Прежде всего strtotime (date (‘Ym-d’)) может быть заменен более элегантным strtotime (‘now’) , но об этом позже. Другая большая ошибка заключается в том, что 60 * 60 * 24 * 30 , то есть количество секунд в 30 днях, может быть задано как константа. В конце концов, результат неправильный, потому что не каждый месяц имеет 30 дней.
Правильный подход
Небольшое исследование проблемы и функций в версиях до 5.3.0 PHP необходимо. Типичный пример форматирования даты происходит при работе с датами из базы данных. Следующий код является классическим примером.
// 2008 05 23, 2008-05-23 is stored into the DB echo date('Y m d', strtotime('2008-05-23')); // 2008 May 23 echo date('Y F d', strtotime('2008-05-23'));
Возможно, проблема в том, что слишком часто strtotime () используется именно так, именно с этим типом строк. Однако гораздо интереснее то, что strtotime () может сделать гораздо больше.
strtotime () может сделать намного больше
Давайте сначала посмотрим на документацию этой функции. Какие параметры он принимает?
int strtotime ( string $time [, int $now = time() ] )
Функция ожидает получить строку, содержащую формат даты на английском языке, и попытается проанализировать этот формат в метку времени Unix (количество секунд с 1 января 1970 года 00:00:00 UTC) относительно отметки времени, указанной в настоящее время, или текущее время, если сейчас не указано.
В частности нас интересует первый параметр, время .
время — строка даты / времени. Допустимые форматы объясняются в форматах даты и времени.
Особенно важно отметить, какие допустимые форматы даты и времени .
Вот поддерживаемые форматы, но наиболее интересными являются относительные .
Именно эти форматы очень удобны в нашем случае, потому что они дают нам возможность работать с читаемыми человеком строками, и вот несколько примеров из документации strtotime ().
echo strtotime("now"), "\n"; echo strtotime("10 September 2000"), "\n"; echo strtotime("+1 day"), "\n"; echo strtotime("+1 week"), "\n"; echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n"; echo strtotime("next Thursday"), "\n"; echo strtotime("last Monday"), "\n";
Таким образом, допустимая строка будет «1 месяц назад».
// if current date is 2011-11-04, this will return 2011-10-04 echo date('Y-m-d', strtotime('1 month ago'))
Или «-1 месяц»:
// the same as the example above echo date('Y-m-d', strtotime('-1 month'));
Интересно, что «+1 -1 месяц» также является допустимой строкой.
// 2011-10-04, if today's 2011-11-04 echo date('Y-m-d', strtotime('+1 -1 month'));
На самом деле strtotime () может сделать намного больше, чем когда-либо представляли большинство разработчиков. Возможно, его частое использование со строковыми форматированными датами (2010-01-13) делает его немного неизвестным. Вот несколько интересных вариантов использования.
// 1970-01-01, Calculations in braces are bad! echo date('Y-m-d', strtotime('(60*60) minute')); // 2 months into the future echo date('Y-m-d', strtotime('-2 months ago'));
Например, вы знаете, как получить дату позавчерашнего дня? Да, за 2 дня до сегодняшнего дня, но вот еще одно решение.
// 1 day before yesterday echo date('Y-m-d', strtotime('yesterday -1 day'));
Другой пример — полностью читабельный человек:
// get the first monday of the current month echo date('Y-m-d', strtotime('first monday this month'));
Решение задачи
Наконец, каково решение исходной задачи? Ну, просто нужно проверить, является ли дата больше или меньше, чем месяц назад.
// a random date $my_date = '2011-09-23'; // true if my_date is more than a month ago (strtotime($my_date) < strtotime('1 month ago'))
Похожие сообщения:
- Что нужно знать о массивах PHP
- javascript получить месяц локали с полным именем
- Строки PHP: как получить расширение файла