如何使用 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的主要内容,如果未能解决你的问题,请参考以下文章

如何使用js获取某月的第一天和最后一天

如何在n个月内使用sql(无程序)获取每个月的第一天和最后一天

获取本周的第一天和最后一天

sql如何取某年某月的第一天和最后一天

如何用sql获取上个月的第一天和上个月的最后一天

在c#中获取上个月的第一天和最后一天的日期