用PHP过去12个月

时间:2011-08-31 20:29:12

标签: php date

所以这是我今天学到的一个有趣的问题。

我需要填充过去12个月的数组,从过去一个月开始。所以在2011年8月,过去12个月将是2010年9月 - 2011年7月。为此,我正在使用:

for ($i = 1; $i <= 12; $i++)
    $months[] = date("Y-m%", strtotime("-$i months"));

上面的代码在8月30日运行正常。我过去12个月了:

array
    0 => string '2011-07%' (length=8)
    1 => string '2011-06%' (length=8)
    2 => string '2011-05%' (length=8)
    3 => string '2011-04%' (length=8)
    4 => string '2011-03%' (length=8)
    5 => string '2011-02%' (length=8)
    6 => string '2011-01%' (length=8)
    7 => string '2010-12%' (length=8)
    8 => string '2010-11%' (length=8)
    9 => string '2010-10%' (length=8)
    10 => string '2010-09%' (length=8)
    11 => string '2010-08%' (length=8)

但是当我在8月31日运行时,我得到了:

array
    0 => string '2011-07%' (length=8)
    1 => string '2011-07%' (length=8)
    2 => string '2011-05%' (length=8)
    3 => string '2011-05%' (length=8)
    4 => string '2011-03%' (length=8)
    5 => string '2011-03%' (length=8)
    6 => string '2011-01%' (length=8)
    7 => string '2010-12%' (length=8)
    8 => string '2010-12%' (length=8)
    9 => string '2010-10%' (length=8)
    10 => string '2010-10%' (length=8)
    11 => string '2010-08%' (length=8)

我尝试过Windows和Unix。有人有解决方案吗?

6 个答案:

答案 0 :(得分:53)

我确信有人会有一个更优雅的解决方案,但你可以从本月1日起开始倒计时。

for ($i = 1; $i <= 12; $i++) {
    $months[] = date("Y-m%", strtotime( date( 'Y-m-01' )." -$i months"));
}

答案 1 :(得分:1)

这是因为不是每个月都有31个。所以strtotime()正在推进到下个月。即4/31 = 5/1。

你最好使用mktime(),因为它是 dumber 而不是strtotime()

更新

要利用strtotime()之类的智能功能并避免跟踪mktime()的年份,以下是我的建议:

$month = time();
for ($i = 1; $i <= 12; $i++) {
  $month = strtotime('last month', $month);
  $months[] = date("r", $month);
}
print_r($months);

根据需要调整逻辑并进行优化。

答案 2 :(得分:1)

我认为这会起作用:

$this_month = date("n", time());
$this_year = date("Y", time());
$months_array = array();
for ($i = $this_month - 1; $i > ($this_month - 13); $i--) {
    echo "$i<br>";
    if ($i < 1) {
        $correct_month_number = $i + 12;
        $months_array[] = array($correct_month_number, $this_year - 1);
    }
    else {
        $months_array[] = array($i, $this_year);
    }
}
echo "<pre>"; var_dump($months_array); echo "</pre>";

数据类型有些松散,但这可以完成工作。这样做的好处是,它只对当前月份和年份调用一次date()函数。其余逻辑只是简单的数学运算。不必担心每个月的时间。

然后,您可以使用$ months_array数组构建所需的任何内容。

答案 3 :(得分:1)

我想用DatePeriod提出另一种解决方案。

这里有很多注意事项。一方面,您不希望遇到诸如时区信息或 / 时间信息之类的问题。您只对月份感兴趣。因此,我们可以对其中一些信息进行规范化处理,以防止发生诸如溢出和夏令时并发症之类的并发症。由于您可以仅在发生这些罕见事件的特定日期/时间容易陷入该陷阱。 / p>

$start = new DateTime;
$start->setDate($start->format('Y'), $start->format('n'), 1); // Normalize the day to 1
$start->setTime(0, 0, 0); // Normalize time to midnight
$start->sub(new DateInterval('P12M'));
$interval = new DateInterval('P1M');
$recurrences = 12;

foreach (new DatePeriod($start, $interval, $recurrences, true) as $date) {
    echo $date->format('F, Y'), "\n"; // attempting to make it more clear to read here
}

输出:

February, 2019
March, 2019
April, 2019
May, 2019
June, 2019
July, 2019
August, 2019
September, 2019
October, 2019
November, 2019
December, 2019
January, 2020

答案 4 :(得分:-3)

不同月份长度的乐趣。 strtotime正在逐字逐句,并采取“8月31日”和tryinn制作“9月31日”,这是不存在的。所以你最终得到10月1日或者其他什么。更安全的方法是:

for ($i = 1; $i <= 12; $i++) {
    $months[] = date("Y-m%", mktime(0, 0, 0, $i, 1, 2011));
}

strtotime有时是神奇的,但它不可靠,当然也不“快”。

答案 5 :(得分:-3)

问题在于,就PHP而言,一个月总是有30天,因此8月31日减1个月仍然是8月。以下代码可能不是最有效或最出色的代码,但它可以完成这项工作:

<?php

$m = strftime('%m');
$y = strftime('%Y');

for($i=1; $i<12; $i++)
{
    $m--;
    if($m <= 0)
    {
        $y--;
        $m = 12;
    }
    print "$y-$m\n";
}

?>