For my situations, I need to set period time finishing our project logics, but here is a problem, how can I mock the now from my setting? Fortunately, the php package Carbon provides a few methods to do this.

$knownDate = Carbon::create(2001, 5, 21, 12);          // create testing date
Carbon::setTestNow($knownDate);                        // set the mock (of course this could be a real mock object)
echo Carbon::getTestNow();                             // 2001-05-21 12:00:00
echo Carbon::now();                                    // 2001-05-21 12:00:00
echo new Carbon();                                     // 2001-05-21 12:00:00
echo Carbon::parse();                                  // 2001-05-21 12:00:00
echo new Carbon('now');                                // 2001-05-21 12:00:00
echo Carbon::parse('now');                             // 2001-05-21 12:00:00
echo Carbon::create(2001, 4, 21, 12)->diffForHumans(); // 1 month ago
var_dump(Carbon::hasTestNow());                        // bool(true)
Carbon::setTestNow();                                  // clear the mock
var_dump(Carbon::hasTestNow());                        // bool(false)
echo Carbon::now();                                    // 2020-07-28 06:16:09

Next, our period can’t overflow a month or a year, for example, when the time is 2019-01-31 for now, I used addMonth than expected 2019-02-28, but no, because the year isn’t leap year, right? So Carbon was automatic to avoid and overflow the month to be 2019-03-03. We can use addMonthsNoOverflow and addYearsNoOverflow to get correct value of time.

$knownDate = \Carbon\Carbon::create(2019, 1, 31);          
\Carbon\Carbon::setTestNow($knownDate);     

now()->addMonthNoOverflow() // 2019-02-28

$knownDate = \Carbon\Carbon::create(2020, 2, 29); // leap year         
\Carbon\Carbon::setTestNow($knownDate);     

now()->addYearNoOverflow() // 2021-02-28

And also it provides a ton of methods, you can find on documentation.

How do I make the method of naming more semantic? Maybe you need tomorrow you do addDay or addDays(1), but internal basic class, provides many semantic methods for you.

Carbon::tomorrow()
Carbon::yesterday()

Comparison is frequency in use, we can use a lot of helpers.

Carbon::isSameDay()
Carbon::eq() = Carbon::equalTo()
Carbon::lte() = Carbon::lessThanOrEqualTo()
Carbon::gte() = Carbon::greaterThanOrEqualTo()

Calculating period months in year.

Carbon::macro('periodMonthsByYearly', function($start, $format = null) {
    $start = Carbon::parse($start);

    $result = [];
    for($i = 1;$i <= $period = 12; $i++) {
        $handle = $start->copy()->addMonthsNoOverflow($i)->subDay()->endOfDay();

        if (! empty($format)) {
            $handle = $handle->format($format);
        }

        array_push($result, $handle);
    }

    return $result;
});

Give it a try.