skip to Main Content

I am looking for a way to determine the next occurrence of a certain day of a month. This would refer to a numbered day (e.g. the next 30th). Every month should always have one eligible date, so in case a particular month doesn’t have the specified day, we wouldn’t overflow to the next one, getting the last day of that month instead.

  • Carbon provides the nthOfMonth function, but it refers to weekdays.
  • I found a couple of answers, but they deal with getting that day next month instead of the next fitting occurrence of a day
    • This answer only provides a start date, while in this case we might be many months or years in the future and we want to "catch up" with a subscription from that point on
    • This answer seems closer, but it seems like it could be made more readable or less verbose with Carbon

Is there any built in function in Carbon that fits this use case? It seems odd to have the nthOfMonth function and other functions with "No Overflow" without getting this case covered in between.

2

Answers


  1. Chosen as BEST ANSWER

    This function finds the next future occurrence of "nth" day of a month (not weekday). This function won't overflow if there aren't enough days in the month, but will jump to the next one if the "nth" day already passed since the closest future date where we can find would be the next month:

    public function nextNthNoOverflow(int $nth, Carbon $from): Carbon
    {
        // Get the fitting day on the $from month as a starting point
        // We do so without overflowing to take into account shorter months
        $day_in_month = $from->copy()->setUnitNoOverflow('day', $nth, 'month');
    
        // If the date found is greater than the $from starting date we already found the next day
        // Otherwise, jump to the next month without overflowing
        return $day_in_month->gt($from) ? $day_in_month : $day_in_month->addMonthNoOverflow();
    }
    

    Since we are using the $from date in the last comparison, we want to make sure to copy() it previously so it doesn't mess the date. Also, depending on your needs, you might consider including equal dates with gte() instead.


  2. To get the next occurrence of a certain day of a month using Carbon, you can use the next() method and pass it a closure that checks if the current date is the day you are looking for.

    use CarbonCarbon;
    
    $date = Carbon::now(); $day = 30; // the 30th of the month
    
    $nextOccurrence = $date->next(function (Carbon $date) use ($day) {
        return $date->day == $day; });
    
    echo $nextOccurrence;
    

    This will output the next occurrence of the 30th day of the month, taking into account the current date. If the current date is already the 30th of the month, it will return the current date.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search