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

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

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

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

// Today is 2011-03-30
echo date('Y-m-d', strtotime('last month'));

// Output:
2011-03-02

Это поведение понятно (до определенной точки) из-за разного количества дней в феврале и марте, а код в приведенном выше примере - это то, что мне нужно, но работает только на 100% правильно между 1 и 28 числами каждого месяца.

Итак, как получить последний месяц И год (подумайте о date("Y-m")) самым элегантным образом, который работает каждый день в году? Оптимальное решение будет основано на анализе аргументов strtotime.

Update. Чтобы немного уточнить требования.

У меня есть фрагмент кода, который получает статистику за последние несколько месяцев, но сначала я показываю статистику за последний месяц, а затем загружаю другие месяцы, когда это необходимо. Это намеченная цель. Итак, в течение этого месяца я хочу узнать, какой месяц-год я должен потянуть, чтобы загрузить ПРЕДЫДУЩИЕ месячные статистические данные.

У меня также есть код, который имеет отношение к часовому поясу (на самом деле это не важно сейчас), и принимает strtotime -собираемую строку в качестве входных данных (для инициализации внутренней даты), а затем позволяет корректировать дату/время, также используя strtotime -связные строки.

Я знаю, что это можно сделать с помощью нескольких условных выражений и базовой математики, но это действительно беспорядочно, по сравнению с этим, например (если оно работает правильно, конечно):

echo tz::date('last month')->format('Y-d')

Итак, я ТОЛЬКО нуждаюсь в предыдущем месяце и году, с strtotime -совместимым способом.

Ответ (спасибо, @dnagirl):

// Today is 2011-03-30
echo date('Y-m-d', strtotime('first day of last month')); // Output: 2011-02-01
4b9b3361

Ответ 1

Посмотрите на класс DateTime. Он должен правильно выполнять вычисления, а форматы даты совместимы с strttotime. Что-то вроде:

$datestring='2011-03-30 first day of last month';
$dt=date_create($datestring);
echo $dt->format('Y-m'); //2011-02

Ответ 2

если сам день не имеет значения, выполните следующее:

echo date('Y-m-d', strtotime(date('Y-m')." -1 month"));

Ответ 3

Я нашел ответ, так как сегодня у меня была такая же проблема, что и 31-я. Это не ошибка в php, как предполагали некоторые, но ожидаемая функциональность (в некоторых из них). В соответствии с этим post то, что 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('Y-m-d', strtotime("last day of -1 month"));
echo date('Y-m-d', strtotime("last day of last month"));
echo date_create("last day of -1 month")->format('Y-m-d'); 

// All the following return 2012-04-01
echo date('Y-m-d', strtotime("first day of -1 month")); 
echo date('Y-m-d', strtotime("first day of last month"));
echo date_create("first day of -1 month")->format('Y-m-d');

Таким образом, используя их, можно создать диапазон дат, если вы делаете запрос и т.д.

Ответ 4

Если вы хотите, чтобы предыдущий год и месяц относились к определенной дате и имели доступ к 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

Ответ 5

date('Y-m', strtotime('first day of last month'));

Ответ 6

strtotime имеют второй параметр timestamp, который делает первый параметр относительно второго параметра. Итак, вы можете сделать это:

date('Y-m', strtotime('-1 month', time()))

Ответ 7

если я правильно понимаю вопрос, вы просто хотите, чтобы в прошлом месяце и в каком году он был:

<?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

Ответ 8

ehh, это не ошибка, как упоминается один человек. это ожидаемое поведение, так как количество дней в месяце часто отличается. Самый простой способ получить предыдущий месяц с использованием strtotime, вероятно, будет использовать -1 месяц с первого числа этого месяца.

$date_string = date('Y-m', strtotime('-1 month', strtotime(date('Y-m-01'))));

Ответ 9

Я думаю, что вы нашли ошибку в функции strtotime. Всякий раз, когда мне приходится обходиться, я всегда нахожусь в математике по значению месяца/года. Попробуйте что-то вроде этого:

$LastMonth = (date('n') - 1) % 12;
$Year      =  date('Y') - !$LastMonth;

Ответ 10

Возможно, немного более длинный, чем вы хотите, но я использовал больше кода, чем, возможно, слишком долго, чтобы он был более читабельным.

Тем не менее, он выходит с тем же результатом, что и вы, - что вы хотите/ожидаете, что он выйдет?

//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('Y-m-d', $today)."<br/>";
echo "Recalulated: ".date("Y-m-d",mktime($hour,$minute,$second,$month-1,$day,$year));

Если вы просто хотите месяц и год, то просто установите день "01", а не "день":

 $day = 1;

Это должно дать вам то, что вам нужно. Вы можете просто установить час, минуту и ​​секунду на ноль, а также вы не заинтересованы в их использовании.

 date("Y-m",mktime(0,0,0,$month-1,1,$year);

Сокращает это немного, -)

Ответ 11

Это связано с тем, что предыдущий месяц имеет меньше дней, чем в текущем месяце. Я исправил это, сначала проверив, имеет ли предыдущий месяц меньше дней, чем текущий, и изменив расчет на основе этого.

Если у него меньше дней, то получите последний день -1 месяц, чтобы получить текущий день -1 месяц:

if (date('d') > date('d', strtotime('last day of -1 month')))
{
    $first_end = date('Y-m-d', strtotime('last day of -1 month'));
}
else
{
    $first_end = date('Y-m-d', strtotime('-1 month'));
}

Ответ 12

Если решение 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);
}

Ответ 13

//return timestamp, use to format month, year as per requirement
function getMonthYear($beforeMonth = '') {
    if($beforeMonth !="" && $beforeMonth >= 1) {
        $date = date('Y')."-".date('m')."-15";
        $timestamp_before = strtotime( $date . ' -'.$beforeMonth.' month' );
        return $timestamp_before;
    } else {
        $time= time();
        return $time;
    }
}


//call function
$month_year = date("Y-m",getMonthYear(1));// last month before  current month
$month_year = date("Y-m",getMonthYear(2)); // second last month before current month

Ответ 14

function getOnemonthBefore($date){
    $day = intval(date("t", strtotime("$date")));//get the last day of the month
    $month_date = date("y-m-d",strtotime("$date -$day days"));//get the day 1 month before
    return $month_date;
}

Результирующая дата зависит от количества дней, из которых состоит входной месяц. Если месяц ввода - февраль (28 дней), за 28 дней до 5 февраля - 8 января. Если вход может быть 17, за 31 день до апреля 16. Аналогичным образом, если ввод может составлять 31, итоговая дата будет 30 апреля.

ПРИМЕЧАНИЕ: ввод принимает полную дату ( "y-m-d" ) и выходы ( "y-m-d" ), вы можете изменить этот код в соответствии с вашими потребностями.

Ответ 15

date("m-Y", strtotime("-1 months")); 

решил бы это