如何使用 Carbon 获取上个月的第一天和最后一天 - Laravel
Posted
技术标签:
【中文标题】如何使用 Carbon 获取上个月的第一天和最后一天 - Laravel【英文标题】:How to get First and Last Day of Previous Month with 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
的结果。
谁能帮我解决这个问题?
【问题讨论】:
【参考方案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以上是关于如何使用 Carbon 获取上个月的第一天和最后一天 - Laravel的主要内容,如果未能解决你的问题,请参考以下文章