Intereting Posts

Как получить предыдущий месяц и год относительно сегодняшнего дня, используя strtotime и дату?

Мне нужно получить предыдущий месяц и год, по сравнению с текущей датой.

Однако см. Следующий пример.

// 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); }