Skip to content

Conversation

@dereuromark
Copy link
Member

Summary

Adds two new methods to Chronos that solve the problem of constructing a relative date that always points to the next (or previous) future occurrence of a specific day and time.

Problem

As described in #406, PHP's relative date parsing with next only considers the date, not the time:

// If it's Tuesday 4pm:
new Chronos('Tue 12:00');       // Tuesday 12pm (in the past!)
new Chronos('next Tue 12:00');  // Next week Tuesday 12pm (always skips to next week)

There's no way to get "the next future occurrence of Tuesday 12pm" that returns today if it's before noon, or next week if it's after noon.

Solution

Two new methods:

  • nextOccurrenceOf(int $dayOfWeek, int $hour, int $minute, int $second) - Returns the next future occurrence, considering both day and time
  • previousOccurrenceOf(int $dayOfWeek, int $hour, int $minute, int $second) - Returns the most recent past occurrence
// If it's Tuesday 9am:
Chronos::now()->nextOccurrenceOf(Chronos::TUESDAY, 12, 0);
// → Today at 12pm (still in the future)

// If it's Tuesday 4pm:
Chronos::now()->nextOccurrenceOf(Chronos::TUESDAY, 12, 0);
// → Next Tuesday at 12pm (today's has passed)

Behavior at exact time

When the current time matches exactly, nextOccurrenceOf returns next week and previousOccurrenceOf returns last week (strict comparison, not inclusive).

Discussion Points

  • Method naming: nextOccurrenceOf vs nextOrSame or something shorter?
  • Should the time be at the exact second, or should it also consider greaterThanOrEquals?

Related to #406

Test plan

  • Tests for same day before/after target time
  • Tests for different day
  • Tests for exact time edge case
  • Tests for seconds parameter
  • All existing tests pass (907 tests)
  • Code style passes

These methods solve the problem of constructing a relative date that
always points to the next (or previous) future occurrence of a
specific day and time.

Unlike next()/previous(), these methods consider BOTH the day AND
the time. If today is the target day:
- nextOccurrenceOf: returns today if time hasn't passed, else next week
- previousOccurrenceOf: returns today if time has passed, else last week

Example:
  // If it's Tuesday 9am, get Tuesday 12pm (today)
  // If it's Tuesday 4pm, get Tuesday 12pm (next week)
  $date = Chronos::now()->nextOccurrenceOf(Chronos::TUESDAY, 12, 0);

Related to #406
@dereuromark dereuromark requested a review from markstory January 28, 2026 17:03
@dereuromark dereuromark changed the base branch from 3.x to 3.next January 28, 2026 17:05
@dereuromark dereuromark marked this pull request as ready for review January 28, 2026 17:06
@dereuromark dereuromark added this to the 3.next milestone Jan 28, 2026
@Bilge
Copy link
Contributor

Bilge commented Jan 28, 2026

Seems OK to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants