【问题标题】:Using PHP date with strtotime to loop months creates duplicates使用 PHP 日期和 strtotime 循环月份会创建重复
【发布时间】:2023-03-11 04:51:01
【问题描述】:

我在 PHP 中有一个循环,它应该得到过去 12 个月的完整时间。今天,5 月 31 日,那些月份的标签似乎重复了。

3 月取代 2 月 十二月取代十一月 10 月取代 9 月

$count = 1;
$date_array = array();
while ($count <= 12) {

    // Calculate date
    $query_year = date('Y', strtotime('-' . $count . ' months America/Chicago'));
    $query_month = date('m', strtotime('-' . $count . ' months America/Chicago'));
    $display_month = date('M', strtotime('-' . $count . ' months America/Chicago'));

    $date_array[] = array(
        'query_year' => $query_year,
        'query_month' => $query_month,
        'display_month' => $display_month
    );

    $count ++;

}

print_r($date_array);

下面是实际代码:http://ideone.com/dBklOH

知道为什么会这样吗?它从今天 5 月 31 日才开始,可能会在明天自行解决。

【问题讨论】:

  • 如果你从 5 月 31 日减去 1 个月,你期望什么..... PHP 应该告诉你 4 月 31 日吗?
  • @MarkBaker 我希望 PHP 能够找到上个月的最后一个日期,即 4 月 30 日。与从 3 月 31 日减去 1 个月相同,我预计会在 2 月 28 日/29 日看到。 1 个月 != 本月的天数
  • @JeffWalden - 那么您的期望是错误的,正如马特的回答中所解释的那样...... PHP 有效地减少了日期 2016-03-31 的月份部分以给出 2016-02-31(调整通过减少第 1 个月的年份,但不调整日期....如果您从计算机的角度考虑,这非常合乎逻辑
  • 这是非常有据可查的行为,已经多次被问及回答。

标签: php


【解决方案1】:

当当月的今天 (31) 在相关月份中不存在时,以编程方式确定过去或未来 N 个月的日期是一个重要的问题。 1 月 31 日之后的 1 个月:2 月 28 日还是 3 月 2 日?显然,人类知道这取决于您所说的“1 个月”是什么意思,但 PHP 选择了后者。

要掌握过去十二个月,最安全的方法是首先将初始日期设置为当月的第一天。

for ($index = 0, $date = new DateTime("first day of this month", new DateTimeZone("America/Chicago"));
     ++$index <= 12; $date->modify("-1 month")) {
    $dates[] = [
        "query_year" => $date->format("Y"),
        "query_month" => $date->format("m"),
        "display_month" => $date->format("M")
    ];
}

或者,使用 PHP 的 date 函数代替 DateTime 类:

for ($index = 0, $date = strtotime("first day of this month America/Chicago");
     ++$index <= 12; $date = strtotime("-1 month", $date)) {
    $dates[] = [
        "query_year" => date("Y", $date),
        "query_month" => date("m", $date),
        "display_month" => date("M", $date)
    ];
}

【讨论】:

    【解决方案2】:

    您的代码的问题是您必须使用当月的第一天作为起点。有些月份有 31 天,有些月份有 30 或 29 天。基于上个月而非当前月份的字符串“-1 月”中的减少天数。

     <?php
             date_default_timezone_set("America/Chicago");
             $count = 0;
             $data_array = array();
             $year_month = date("Y-m");
             $first_day = strtotime("$year_month-01 00:00:00");
             while ($count < 12) {
                 $query_year = date("Y", strtotime("-".$count." months", $first_day));
                 $query_month = date("m", strtotime("-".$count." months", $first_day));
                 $display_month = date("M", strtotime("-".$count." months", $first_day));
                 $date_array[] = array(
                     "query_year" => $query_year,
                     "query_month" => $query_month,
                     "display_month" => $display_month
                 );
                 $count++;
            }
            print_r($date_array);
        ?>
    

    【讨论】:

    • 请添加说明您的代码在做什么的文字,而不是仅仅将您的所有代码作为答案。
    • @HunterTurner 感谢您的建议。我在使用英语方面有些困难,但我会尽力而为。
    【解决方案3】:
    <?php
    
    $date = new DateTime('first day of this month', new DateTimeZone('America/Chicago'));
    $dates = [];
    for($i = 12; $i>0;$i--) {
        $dates[] = [
            'query_year' => $date->format('Y'),
            'query_month' => $date->format('m'),
            'display_month' => $date->format('M'),
        ];
        $date->sub(new DateInterval("P1M"));
    }
    var_dump($dates);
    

    【讨论】:

    • 这是什么意思? $date->sub(new DateInterval("P1M"));
    • 'P1M' 是 1 month 的 iso 标准周期表示;
    • P - 周期,1M - 1 个月
    • 这段代码对我来说不能正常工作。它重复第一个月(五月)。
    • now引起。我编辑了代码并完美运行:)
    【解决方案4】:

    我使用这个简单的代码来循环几个月

    $year_month = date("Ym");
    for($i=0;$i<12;$i++)
    {
         $year_month = date("Ym",strtotime("-$i month",strtotime($year_month)));
         print $i." - ".$year_month."<br/>";
    }
    

    【讨论】:

      猜你喜欢
      • 2021-11-26
      • 1970-01-01
      • 2013-09-21
      • 1970-01-01
      • 2018-10-15
      • 2012-02-21
      • 1970-01-01
      • 2015-06-20
      • 2017-01-27
      相关资源
      最近更新 更多