【问题标题】:How to get First and Last Day of Previous Month with Carbon - Laravel如何使用 Carbon 获取上个月的第一天和最后一天 - Laravel
【发布时间】:2016-09-06 08:08:33
【问题描述】:

我需要上个月第一天最后一天使用碳库,我尝试过的方法如下:

$firstDayofPreviousMonth = Carbon::now()->startOfMonth()->subMonth()->toDateString();
$lastDayofPreviousMonth = Carbon::now()->endOfMonth()->subMonth()->toDateString();

我得到的结果是$firstDayofPreviousMonth = '2016-04-01'(因为当前月份是 5 日(5 月))和 $lastDayofPreviousMonth = '2016-05-01'

我得到了 $firstDayofPreviousMonth 的正确结果,但它给了我 30 天前的结果,并且给了我错误的 $lastDayofPreviousMonth 的结果。

谁能帮我解决这个问题?

【问题讨论】:

    标签: php laravel date php-carbon


    【解决方案1】:

    这对我有用。

    $firstDayofPreviousMonth = Carbon::now()->startOfMonth()->subMonth()->toDateTimeString(); // 2021-08-01 00:00:00
    $lastDayofPreviousMonth = Carbon::now()->endOfMonth()->subMonth()->toDateTimeString(); // 2021-08-31 23:59:59
    

    使用单个 $date 变量

    $date = Carbon::now();
    
    $firstDayofPreviousMonth = $date->startOfMonth()->subMonth()->toDateTimeString(); // 2021-08-01 00:00:00
    
    $lastDayofPreviousMonth = $date->endOfMonth()->toDateTimeString(); // 2021-08-31 23:59:59
    

    【讨论】:

      【解决方案2】:

      试试这个

      $firstDayofPreviousMonth = Carbon::now()->startOfMonth()->subMonth()->toDateString();
      $lastDayofPreviousMonth = Carbon::now()->subMonth()->endOfMonth()->toDateString();
      

      更新代码,更准确

      $firstDayofPreviousMonth = Carbon::now()->startOfMonth()->subMonthsNoOverflow()->toDateString();
      
      $lastDayofPreviousMonth = Carbon::now()->subMonthsNoOverflow()->endOfMonth()->toDateString();
      

      @kenfai 谢谢

      【讨论】:

      • 这绝对是最好的,因为它从 00:00 开始,到 23:59:59 结束。公认的解决方案不考虑时间,可能会产生不可靠的结果。
      • 我只想指出,由于 PHP DateTime 溢出问题,您可能想使用 subMonthNoOverflow() 代替。更多讨论:github.com/briannesbitt/Carbon/issues/428
      • @kenfai 谢谢我已经更新了代码示例
      • 谢谢!因为我有每月 31 天的问题
      【解决方案3】:

      另一种解决方案是使用Carbon方法subMonthNoOverflow()

      $lastDayofPreviousMonth = Carbon::now()->subMonthNoOverflow()->endOfMonth()->toDateString();
      

      遇到每月 31 天的问题时在这里找到它:https://github.com/briannesbitt/Carbon/issues/627

      【讨论】:

        【解决方案4】:

        专门回答您关于为什么$lastDayofPreviousMonth 得到错误结果的问题。

        让我们在您的示例中分解此语句:

        Carbon::now()->endOfMonth()->subMonth()->toDateString();
        // Carbon::now() > 2016-05-05
        // ->endOfMonth() > 2016-05-31
        // ->subMonth() > 2016-04-31 // Simply takes 1 away from 5.
        

        这给我们留下了一个无效的日期——没有 4 月 31 日。额外的一天只是简单地添加到最后一个有效日期 (2016-04-30 + 1) 上,这会将日期滚动到 5 月 (2016-05-01)。

        如前所述,为了确保永远不会发生这种情况,请始终在执行任何其他操作之前将日期重置为当月的 1 日(因为每个月都有第一天)。

        $lastDayofPreviousMonth = Carbon::now()->startofMonth()->subMonth()->endOfMonth()->toDateString();
        // Carbon::now() > 2016-05-05
        // ->startofMonth() > 2016-05-01 00:00:00
        // ->subMonth() > 2016-04-01 00:00:00
        // ->endOfMonth() > 2016-04-30 23:59:59
        

        【讨论】:

          【解决方案5】:

          有了这个......日期从 00:00 开始初始化,日期在 23:59 结束

          $start = new Carbon('first day of last month');
          $start->startOfMonth();
          $end = new Carbon('last day of last month');
          $end->endOfMonth();
          

          【讨论】:

          • 这应该是正确的答案,因为它也比较时间。
          【解决方案6】:

          使用该方法时,Carbon 中目前存在一个错误

          Carbon::now()->startOfMonth()->subMonth()->endOfMonth()->toDateTimeString();
          

          该错误导致那些有 31 天的月份的最后一天返回 30。

          IE - 如果您在 3 月份运行上述调用,它将返回 2017-03-30 而不是 2017-03-31,如您所料。

          当我在进行日期之间的操作时,我最终使用了..

          Carbon::now()->startOfMonth()->subSeconds(1)->toDateTimeString();
          

          这以 31 日结束的那几天的正确日期 dateTimeString 结束。

          【讨论】:

            【解决方案7】:

            试试这个:

            $start = new Carbon('first day of last month');
            $end = new Carbon('last day of last month');
            

            【讨论】:

            • 没有得到时间为 00:00:00
            • 如您所见,他正在尝试过滤一些数据。你的解决方案给了他错误的结果。请编辑您的答案,让他看到确切的结果,那么就没有理由拒绝投票。
            • 我不管你怎么想,既然问这个,他也不知道该怎么办。所以多亏了你,他可能过滤错了。
            • 这确实不正确,我的公司一直在使用此代码,但它返回了错误的日期。以我的经验,Ozan 是完全正确的,它现在有效,以后不会。 @Abu Sayem 他的回答对我很有效
            • 这是正确的答案。您也可以与endOfDay()startOfDay() 组合得到23:59:59 或00:00:00
            猜你喜欢
            • 2013-02-15
            • 1970-01-01
            • 1970-01-01
            • 2015-04-03
            • 2013-11-25
            • 2014-03-22
            • 1970-01-01
            • 2019-09-10
            • 2011-11-24
            相关资源
            最近更新 更多