php-如何使用strtotime和date获得相对于今天的上个月和一年?

我需要获取相对于当前日期的前一个月和年份。

但是,请参见以下示例。

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

// Output:
2011-03-02

由于2月和3月的天数不同,这种行为在一定程度上是可以理解的,上面的示例中的代码是我所需要的,但是在每个月的1号到28号之间只能正确地工作100%。

那么,如何以最优雅的方式获得上个月AND year(以2570952227506606619392为例),该方法适用于一年中的每一天? 最佳解决方案将基于strtotime参数解析。

更新。 为了澄清需求。

我有一段代码可以获取最近几个月的统计信息,但是我首先显示上个月的统计信息,然后在需要时加载其他月份的统计信息。 这是预期的目的。 因此,在这个月中,我想找出要加载上一个月统计数据的年份。

我还有一个可识别时区的代码(现在并不十分重要),它接受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
mr.b asked 2019-10-15T22:27:42Z
14个解决方案
46 votes

看看strttotime类。 它应该正确进行计算,并且日期格式与strttotime兼容。类似以下内容:

$datestring='2011-03-30 first day of last month';
$dt=date_create($datestring);
echo $dt->format('Y-m'); //2011-02
dnagirl answered 2019-10-15T22:27:54Z
26 votes

如果一天本身没有关系,请执行以下操作:

echo date('Y-m-d', strtotime(date('Y-m')." -1 month"));
ITroubs answered 2019-10-15T22:28:17Z
22 votes

我找到了答案,因为今天我有第31个同样的问题。 正如某些人所建议的那样,它不是php中的错误,而是预期的功能(此后有些)。 根据这篇文章,strtotime实际执行的操作是将月份设置为1,并且不会修改天数。 因此,如果今天是5月31日,它将寻找4月31日,这是无效的日期。 因此,这需要4月30日,然后经过1天,并在5月1日产生。

在您的示例2011-03-30中,该时间可以追溯到2月30日一个月,这是无效的,因为2月只有28天。 然后,需要间隔那几天(30-28 = 2),然后在2月28日(即3月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');

因此,如果您进行查询等,使用这些就可以创建日期范围。

SeanDowney answered 2019-10-15T22:29:03Z
9 votes

如果您想要相对于特定日期的上一年和一个月,并且具有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
Timo Huovinen answered 2019-10-15T22:29:27Z
6 votes
date('Y-m', strtotime('first day of last month'));
Marek answered 2019-10-15T22:29:44Z
5 votes

如果我正确理解了这个问题,那么您只想要上个月和所在的年份:

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

Neal answered 2019-10-15T22:30:15Z
5 votes

strtotime具有第二个参数timestamp,它们使第一参数相对于第二参数。 因此,您可以执行以下操作:

date('Y-m', strtotime('-1 month', time()))
dieend answered 2019-10-15T22:30:39Z
4 votes

嗯,这不是一个人提到的错误。 这是预期的行为,因为一个月中的天数通常不同。 使用strtotime获取上个月的最简单方法可能是从本月的第一个月开始使用-1个月。

$date_string = date('Y-m', strtotime('-1 month', strtotime(date('Y-m-01'))));
dqhendricks answered 2019-10-15T22:31:04Z
2 votes

我认为您在strtotime函数中发现了一个错误。 每当我必须解决此问题时,我总是发现自己会根据月/年值进行数学运算。 尝试这样的事情:

$LastMonth = (date('n') - 1) % 12;
$Year      =  date('Y') - !$LastMonth;
Zach Rattner answered 2019-10-15T22:31:28Z
1 votes

也许缠绕的时间比您想要的长一些,但是为了使它更具可读性,我使用了不必要的代码。

也就是说,结果与您得到的结果相同-您想要/期望它得到什么?

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

减少很多;-)

Codecraft answered 2019-10-15T22:32:19Z
1 votes

这是因为上个月的天数少于当前月的天数。 我已经解决了这一问题,方法是先检查上个月的日期是否少于当前日期,然后根据该日期更改计算。

如果天数较少,则获取-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'));
}
RJD22 answered 2019-10-15T22:32:50Z
0 votes

如果可以使用DateTime解决方案,则此代码段将返回上个月的年份和上个月的月份,从而避免在1月运行此代码时可能出现的陷阱。

function fn_LastMonthYearNumber()
{
 $now = new DateTime();
 $lastMonth = $now->sub(new DateInterval('P1M'));
 $lm= $lastMonth->format('m');
 $ly= $lastMonth->format('Y');
 return array($lm,$ly);
}
zzapper answered 2019-10-15T22:33:15Z
0 votes
//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
Mukesh answered 2019-10-15T22:33:33Z
0 votes
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;
}

结果日期取决于输入月份所包含的天数。 如果输入月份为2月(28天),则2月5日为1月8日之前的28天。如果输入为5月17日,则是4月16日之前的31天。同样,如果输入为5月31日,则得出的日期将是4月30日。

注意:输入需要完整日期('y-m-d')和输出('y-m-d'),您可以修改此代码以适合您的需要。

Elijah Dadibalos answered 2019-10-15T22:34:04Z
translate from https://stackoverflow.com:/questions/5489502/how-to-get-previous-month-and-year-relative-to-today-using-strtotime-and-date