How to get previous month and year relative to today, using strtotime and date?
我需要获取相对于当前日期的前一个月和年份。
但是,请参见以下示例。
由于2月和3月的天数不同,这种行为在一定程度上是可以理解的,上面的示例中的代码是我所需要的,但是在每个月的1号到28号之间只能正确地工作100%。
那么,如何以最优雅的方式获取上个月的AND年(认为是
更新。为了澄清需求。
我有一段代码可以获取最近几个月的统计信息,但是我首先显示上个月的统计信息,然后在需要时加载其他月份的统计信息。这是预期的目的。因此,在这个月中,我想找出要加载上一个月统计信息的年份。
我还有一个可识别时区的代码(现在并不十分重要),并且接受与
我知道只需很少的条件和基本数学就可以完成此操作,但是与之相比,这确实很麻烦(例如,如果工作正常,那么):
1 |
因此,我只需要以
答案(谢谢@dnagirl):
1 2 |
看一下
1 2 3 | $datestring='2011-03-30 first day of last month'; $dt=date_create($datestring); echo $dt->format('Y-m'); //2011-02 |
如果一天本身没有关系,请执行以下操作:
我找到了答案,因为今天我有第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对象添加"第一天"或"最后一天":
1 2 3 4 5 6 7 8 9 10 | // 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'); |
因此,如果您进行查询等,使用这些就可以创建日期范围。
如果您想要相对于特定日期的上一年和一个月,并具有DateTime可用,则可以执行以下操作:
1 2 3 4 | $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 |
如果我正确地理解了这个问题,那么您只想要上个月和所在的年份:
1 2 3 4 5 6 7 8 |
这是示例:http://codepad.org/c99nVKG8
嗯,这不是一个人提到的错误。这是预期的行为,因为一个月中的天数通常不同。使用strtotime获取上个月的最简单方法可能是从本月的第一个月开始使用-1个月。
我认为您在strtotime函数中发现了一个错误。每当我必须解决此问题时,我总是发现自己会根据月/年值进行数学运算。尝试这样的事情:
这是因为上个月的天数少于当前月的天数。我已经解决了这一问题,方法是先检查上个月的日期是否少于当前日期,然后根据该日期更改计算。
如果天数较少,则获取-1个月的最后一天,否则获取当前的-1个月:
1 2 3 4 5 6 7 8 |
也许缠绕的时间比您想要的长一些,但是为了使它更具可读性,我使用了不必要的代码。
也就是说,结果与您得到的结果相同-您想要/期望它得到什么?
1 2 3 4 5 6 7 8 9 10 11 12 | //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",而不是"今天":
1 | $day = 1; |
那应该给您您需要的。您可以将小时,分钟和秒设置为零,也可以将它们设置为零。
减少很多;-)
会解决这个问题
1 2 3 4 5 |
结果日期取决于输入月份所包含的天数。如果输入月份为2月(28天),则2月5日为1月8日之前的28天。如果输入为5月17日,则是4月16日之前的31天。同样,如果输入为5月31日,则得出的日期将是4月30日。
注意:输入需要完整日期('y-m-d')和输出('y-m-d'),您可以修改此代码以适合您的需要。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //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 |
如果可以使用DateTime解决方案,则此代码段将返回上个月的年份和上个月的月份,从而避免在1月运行此代码时可能出现的陷阱。
1 2 3 4 5 6 7 8 | function fn_LastMonthYearNumber() { $now = new DateTime(); $lastMonth = $now->sub(new DateInterval('P1M')); $lm= $lastMonth->format('m'); $ly= $lastMonth->format('Y'); return array($lm,$ly); } |