相对于当前日期,我需要获得上个月和上年。
但是,请参阅以下示例。
// Today is 2011-03-30
echo date('Y-m-d', strtotime('last month'));
// Output:
2011-03-02
由于2月和3月的天数不同,这种行为是可以理解的(在某一点上),上面的例子中的代码是我需要的,但在每个月的1号和28号之间只能正确地工作100%。
那么,如何以最优雅的方式获得上个月和一年(想象date("Y-m")
),这适用于一年中的每一天?最佳解决方案将基于strtotime
参数解析。
更新。为了澄清要求。
我有一段代码可以获得过去几个月的统计数据,但我首先显示上个月的统计数据,然后在需要时加载其他月份。这是预期的目的。所以,在这个月里,我想知道我应该在哪个月份来加载上个月的统计数据。
我还有一个时区感知的代码(现在不是很重要),接受strtotime
- 兼容字符串作为输入(初始化内部日期),然后允许调整日期/时间,也使用strtotime
- 兼容的字符串。
我知道可以用很少的条件和基本的数学来完成,但与此相比,这是非常混乱的(例如,如果它正常工作):
echo tz::date('last month')->format('Y-d')
所以,我只需要前一个月和一年,以strtotime
兼容的方式。
回答(谢谢,@ ndagirl):
// Today is 2011-03-30
echo date('Y-m-d', strtotime('first day of last month')); // Output: 2011-02-01
答案 0 :(得分:46)
查看DateTime
课程。它应该正确地进行计算,并且日期格式与strttotime
兼容。类似的东西:
$datestring='2011-03-30 first day of last month';
$dt=date_create($datestring);
echo $dt->format('Y-m'); //2011-02
答案 1 :(得分:27)
如果这一天本身无关紧要:
echo date('Y-m-d', strtotime(date('Y-m')." -1 month"));
答案 2 :(得分:23)
我找到了答案,因为我今天遇到了同样的问题,这是第31个问题。这不是某些人所建议的bug in php,而是预期的功能(在某些情况下)。根据这个post 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对象添加“first day of”或“last day of”:
// 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');
因此,如果您进行查询等,可以使用这些来创建日期范围。
答案 3 :(得分:9)
如果您希望上一年和每月相对于特定日期并且有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
答案 4 :(得分:6)
date('Y-m', strtotime('first day of last month'));
答案 5 :(得分:5)
如果我正确地理解了这个问题,你只需要上个月和它所在的年份:
<?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);
?>
答案 6 :(得分:5)
strtotime
具有第二个timestamp
参数,该参数使第一个参数相对于第二个参数。所以你可以这样做:
date('Y-m', strtotime('-1 month', time()))
答案 7 :(得分:4)
$date_string = date('Y-m', strtotime('-1 month', strtotime(date('Y-m-01'))));
答案 8 :(得分:2)
我认为您在strtotime函数中发现了一个错误。每当我必须解决这个问题时,我总会发现自己在月/年值上做数学。尝试这样的事情:
$LastMonth = (date('n') - 1) % 12;
$Year = date('Y') - !$LastMonth;
答案 9 :(得分:1)
也许比你想要的稍长一些,但我使用了更多的代码而不是必要的代码,以使它更具可读性。
那就是说,结果与你得到的结果相同 - 你想要什么/期望它出来?
//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);
把它剪掉了很多; - )
答案 10 :(得分:1)
这是因为前一个月的天数少于当月。我已经通过首先检查前一个月是否有更少的当前天数并根据它改变计算来解决这个问题。
如果天数少于-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'));
}
答案 11 :(得分:0)
如果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);
}
答案 12 :(得分:0)
//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
答案 13 :(得分:0)
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日前的28天是1月8日。如果输入是17月31日,则是4月16日。同样,如果输入是31,则生成日期将是4月30日。
注意:输入采用完整日期(&#39; ym-d&#39;)和输出(&#39; ym-d&#39;)您可以修改此代码以适应您的需求。
答案 14 :(得分:0)
date("m-Y", strtotime("-1 months"));
将解决此问题