碳按数字获取月份返回数字2

时间:2018-08-29 08:21:48

标签: php php-carbon

以前有没有人遇到此错误,或者知道一种解决方法?

我想以数组的形式获取当年所有月份的列表(开始日期和结束日期),所以我正在这样做(接受更清洁更简便方法的建议)

//Create a months array
$months = [];
//Get start and end of all months
for($i = 1; $i <= 12; $i++){
   $array = [];
   $array['start'] = Carbon::create()->month($i)->startOfMonth()->format('d/m/y');
   $array['end'] = Carbon::create()->month($i)->endOfMonth()->format('d/m/y');
   array_push($months, $array);
}

哪个会产生此结果

enter image description here

如您所见,它循环并检索了月份,但请注意,它完全跳过了2月,并两次添加了3月。

如果我手动运行并返回此代码

return Carbon::create()->month(2)->startOfMonth()->format('d/m/y');

它返回01/03/2018

为什么第二个月的三月份会打印出碳?有没有人曾经遇到过这个问题或知道过解决方法?

4 个答案:

答案 0 :(得分:2)

Carbon::create()->month(2)将首先创建今天的日期,然后将月份设置为 2 ,但保留其他值。由于今天的日期是8月29日,因此该日期最终以2月29日为基准,该日期(至少是今年)不存在。 PHP将这些“伪造”日期累积到下个月,因此 2月29日变为 3月1日

如果您首先明确设置月份中的某天,则应该可以正常工作:

Carbon::create()->day(1)->month($i);

(此外,如果您昨天尝试过此方法,它将很好用,并且您可能永远不会注意到该错误。如果明天进行尝试,则可能会在3月2日结束,并且可能注意到它的速度要快得多。日期很有趣。)

答案 1 :(得分:1)

纯PHP就足够了:

$datePeriod = new \DatePeriod(
    new \DateTimeImmutable(date('01-01-Y')),
    new \DateInterval('P1M'),
    new \DateTimeImmutable(date('31-12-Y'))
);

$dates = [];
foreach ($datePeriod as $date) {
     $dates[] = [
         'start' => $date->modify('first day of this month')->format('d/m/y'),
         'end' => $date->modify('last day of this month')->format('d/m/y'),
     ];   
}

答案 2 :(得分:0)

根据外观为0。因此month(0)将是一月,1 =二月,依此类推。 将循环更改为

for($i = 0; $i < 12; $i++){
   $array = [];
   $array['start'] = Carbon::create()->month($i)->startOfMonth()->format('d/m/y');
   $array['end'] = Carbon::create()->month($i)->endOfMonth()->format('d/m/y');
   array_push($months, $array);
}

答案 3 :(得分:0)

在评论建议的答案时想到了这一点。

这是因为今天是2018年8月29日,而2月没有29天。

基本上Carbon会从今天起使用Carbon::create()创建一个实例,但是当使用->month(2)时,它将尝试获取2月29日的错误。它需要从每月的第一天开始工作,因此将其更改为

 Carbon::create()->startOfMonth()->month($i)->startOfMonth()->format('d/m/y');

因此它从该月的1号开始引用,并且可以正常工作。