Я искал решение как узнать последнее число месяца в PHP с учётом високосного года и при этом не использовать timestamp, и ничего не нашёл, пришлось написать функцию самому.
Не использовать timestamp можно по разным причинам, например вы можете писать калькулятор который будет использовать даты больше чем позволяет использовать unix timestamp (больше 2038 года).
Итак, я написал свою функцию, которая вычисляет последний день месяца учитывая високосные года.
Получить последний день месяца с учётом високосного года
// ВАРИАНТ 1
/**
* Высчитывает последнее число месяца
* @param $dateInISO8601 Дата в формате гггг-мм-дд
* @return bool|int false в случае ошибки и последнее число месяца в случае успеха
*/
function getLastDayOfMonth($dateInISO8601)
{
// Проверяем дату на корректность
$date = explode('-', $dateInISO8601);
if ( !checkdate ( $date[1] , $date[2] , $date[0] ) )
return false;
$start = new DateTime( $dateInISO8601 );
$end = new DateTime( $dateInISO8601 );
$end->add( new DateInterval( 'P2M' ) );
$interval = new DateInterval( 'P1D' );
$daterange = new DatePeriod($start, $interval, $end);
$prev = $start;
// Проходимся по периодам, если номер месяца
// предыдущего периода не совпадает с текущим номером месяца
// то возвращаем последний день предыдущего месяца
foreach ($daterange as $date)
{
if ($prev->format('m') != $date->format('m') )
return (int) $prev->format('d');
$prev = $date;
}
return false;
}
// Примеры использования:
echo getLastDayOfMonth('2012-02-01'); // Выведет 29
echo getLastDayOfMonth('2014-02-01'); // Выведет 28
echo getLastDayOfMonth('2014-06-14'); // Выведет 30
// ВАРИАНТ 2
// Этот вариант предложил пользователь buk (см. комментарии)
$day=new DateTime(‘2012-02-01′); echo $day->format(‘t’);
Сложновато получилось. Есть вариант проще, буквально в одну строку. Берем дату, находим первый день месяца, потом прибавляем месяц, и вычитаем один день.
Примерно вот так:
$date2 = date(«Y-m-d», strtotime(date(«Y-m-01″, strtotime($date1.» +1 month»)).» -1 day»));
Ваш способ элегантный! Согласен, что у меня вышло через чур сложно, даже с учётом того, что нельзя использовать timestamp, можно было бы сделать проще)
Хотя вы не хотели использовать timestamp…
date(‘Y-m-d’, strtotime(‘last day’));
Сергей, задача стояла «не использовать timestamp».
date(‘t’);
$day=new DateTime(‘2012-02-01’); echo $day->format(‘t’);
Да, действительно ваш вариант гораздо лучше чем моя велосипедная функция. Спасибо!
format ведь юзает функцию date()… А если я правильно понял, то её использование исключено или нет? 🙂 просто
$day=new DateTime(‘2012-02-01’); echo $day->format(‘t’);
это тоже самое что и
date(‘t’);
только в другой руке.
Для меня главной задачей было использовать старые исторические даты, а с помощью timestamp этого добиться нельзя, например: $day=new DateTime(‘1900-02-01’); echo $day->format(‘t’);
А так не судьба?
echo DATE(‘d’, strtotime(«last Day»));
Так ведь тут же timestamp используется — strtotime ведь timestamp выдаст. Но ход мысли интересный)