Мне нужно получить предыдущий месяц и год, по сравнению с текущей датой.
Однако см. Следующий пример.
// Today is 2011-03-30 echo date('Ym-d', strtotime('last month')); // Output: 2011-03-02
Это поведение понятно (до определенной точки) из-за разного количества дней в феврале и марте, а код в приведенном выше примере – это то, что мне нужно, но работает только на 100% правильно между 1 и 28 числами каждого месяца.
Итак, как получить последний месяц И год (подумайте о date("Ym")
) самым элегантным способом, который работает на каждый день в году? Оптимальное решение будет основано на strtotime
аргументов strtotime
.
Обновить. Чтобы немного уточнить требования.
У меня есть код, который получает статистику за последние пару месяцев, но я сначала показываю статистику за последний месяц, а затем загружаю другие месяцы, когда это необходимо. Это намеченная цель. Итак, в ЭТОМ месяце, я хочу узнать, какой месяц-год я должен потянуть, чтобы загрузить ПРЕДЫДУЩИЕ месячные статистические данные.
У меня также есть код, который имеет отношение к strtotime
(не очень важно прямо сейчас) и принимает strtotime
совместимую строку в качестве входного (для инициализации внутренней даты), а затем позволяет корректировать дату / время, также используя strtotime
совместимые строки ,
Я знаю, что это можно сделать с помощью нескольких условностей и базовой математики, но это действительно грязно, по сравнению с этим, например (если оно работает правильно, конечно):
echo tz::date('last month')->format('Y-d')
Таким образом, я ТОЛЬКО нуждаюсь в предыдущем месяце и году, в strtotime
совместимой манере.
Ответ (спасибо, @dnagirl):
// Today is 2011-03-30 echo date('Ym-d', strtotime('first day of last month')); // Output: 2011-02-01
Посмотрите на класс DateTime
. Он должен правильно выполнять вычисления, а форматы даты совместимы с strttotime
. Что-то вроде:
$datestring='2011-03-30 first day of last month'; $dt=date_create($datestring); echo $dt->format('Y-m'); //2011-02
Я нашел ответ, поскольку сегодня у меня была такая же проблема, что и 31-я. Это не ошибка в php, как предполагали некоторые, но ожидаемая функциональность (в некоторых случаях). Согласно этому сообщению, которое на самом деле делает strtotime, устанавливается месяц назад одним и не изменяет количество дней. Таким образом, в случае с 31 мая, он ищет 31 апреля, что является недопустимой датой. Таким образом, он принимает 30 апреля, а затем добавляет 1 день мимо него и дает 1 мая.
В вашем примере 2011-03-30 он вернется с одного месяца до 30 февраля, что недействительно с февраля только на 28 дней. Затем он принимает разницу в те дни (30-28 = 2), а затем движется через два дня после 28 февраля, что является 2 марта.
Как указывали другие, лучший способ получить «последний месяц» – добавить либо «первый день», либо «последний день», используя либо strtotime, либо объект DateTime:
// Today being 2012-05-31 //All the following return 2012-04-30 echo date('Ym-d', strtotime("last day of -1 month")); echo date('Ym-d', strtotime("last day of last month")); echo date_create("last day of -1 month")->format('Ym-d'); // All the following return 2012-04-01 echo date('Ym-d', strtotime("first day of -1 month")); echo date('Ym-d', strtotime("first day of last month")); echo date_create("first day of -1 month")->format('Ym-d');
Таким образом, используя их, можно создать диапазон дат, если вы делаете запрос и т. Д.
если сам день не имеет значения, выполните следующее:
echo date('Ym-d', strtotime(date('Y-m')." -1 month"));
Если вы хотите, чтобы предыдущий год и месяц относились к определенной дате и имели доступность DateTime, вы можете сделать это:
$d = new DateTime('2013-01-01', new DateTimeZone('UTC')); $d->modify('first day of previous month'); $year = $d->format('Y'); //2012 $month = $d->format('m'); //12
date('Y-m', strtotime('first day of last month'));
strtotime
имеет второй timestamp
параметр, который делает первый параметр относительно второго параметра. Таким образом, вы можете сделать это:
date('Y-m', strtotime('-1 month', time()))
если я правильно понял вопрос, вы просто хотите в прошлом месяце и году, в котором он находится:
<?php $month = date('m'); $year = date('Y'); $last_month = $month-1%12; echo ($last_month==0?($year-1):$year)."-".($last_month==0?'12':$last_month); ?>
Вот пример: http://codepad.org/c99nVKG8
ehh, это не ошибка, как упоминается один человек. это ожидаемое поведение, так как количество дней в месяце часто отличается. Самый простой способ получить предыдущий месяц с использованием strtotime, вероятно, будет использовать -1 месяц с первого числа этого месяца.
$date_string = date('Y-m', strtotime('-1 month', strtotime(date('Ym-01'))));
Я думаю, вы нашли ошибку в функции strtotime. Всякий раз, когда мне приходится обходиться, я всегда нахожусь в математике по значению месяца / года. Попробуйте что-то вроде этого:
$LastMonth = (date('n') - 1) % 12; $Year = date('Y') - !$LastMonth;
Возможно, немного более длинный, чем вы хотите, но я использовал больше кода, чем, возможно, слишком долго, чтобы он был более читабельным.
Тем не менее, он выходит с тем же результатом, что и вы, – что вы хотите / ожидаете, что он выйдет?
//Today is whenever I want it to be. $today = mktime(0,0,0,3,31,2011); $hour = date("H",$today); $minute = date("i",$today); $second = date("s",$today); $month = date("m",$today); $day = date("d",$today); $year = date("Y",$today); echo "Today: ".date('Ym-d', $today)."<br/>"; echo "Recalulated: ".date("Ymd",mktime($hour,$minute,$second,$month-1,$day,$year));
Если вы просто хотите месяц и год, то просто установите день «01», а не «день»:
$day = 1;
Это должно дать вам то, что вам нужно. Вы можете просто установить час, минуту и секунду на ноль, а также вы не заинтересованы в их использовании.
date("Ym",mktime(0,0,0,$month-1,1,$year);
Обрезает это совсем немного 😉
Это связано с тем, что в предыдущем месяце было меньше дней, чем в текущем месяце. Я исправил это, сначала проверив, имеет ли предыдущий месяц меньше дней, чем текущий, и изменив расчет на основе этого.
Если у него меньше дней, то получите последний день -1 месяц, чтобы получить текущий день -1 месяц:
if (date('d') > date('d', strtotime('last day of -1 month'))) { $first_end = date('Ym-d', strtotime('last day of -1 month')); } else { $first_end = date('Ym-d', strtotime('-1 month')); }
Если решение DateTime приемлемо, этот фрагмент возвращает год последнего месяца и месяца прошлого месяца, избегая возможной ловушки, когда вы запускаете это в январе.
function fn_LastMonthYearNumber() { $now = new DateTime(); $lastMonth = $now->sub(new DateInterval('P1M')); $lm= $lastMonth->format('m'); $ly= $lastMonth->format('Y'); return array($lm,$ly); }