Add DayOfWeek and TimeOfDay classes. Refactor Duration and Period methods.#5
Add DayOfWeek and TimeOfDay classes. Refactor Duration and Period methods.#5gustavofreze merged 1 commit intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the TinyBlocks time domain with DayOfWeek and TimeOfDay, while refactoring Duration and Period APIs (factories/accessors/exceptions) and updating tests/docs to match the new interfaces.
Changes:
- Add
DayOfWeek(ISO-8601 weekday enum) andTimeOfDay(HH:MM value object) with corresponding tests and README documentation. - Refactor
Durationto use an internalSecondsvalue object, introduceInvalidSeconds, adddivide(), and switch tofrom*()factories +toSeconds()accessor. - Rename
Period::of()toPeriod::from()and update usages across tests and README.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/DayOfWeek.php |
Adds ISO-8601 weekday enum with helpers and fromInstant() factory. |
src/TimeOfDay.php |
Adds hour/minute value object with parsing, formatting, comparison, and duration calculations. |
src/Duration.php |
Refactors factories/accessors, introduces division, and delegates arithmetic/validation to Internal\Seconds. |
src/Internal/Seconds.php |
New internal non-negative seconds primitive with arithmetic and validation. |
src/Internal/Exceptions/InvalidSeconds.php |
New exception type replacing InvalidDuration for non-negative seconds invariants. |
src/Internal/Exceptions/InvalidTimeOfDay.php |
New exception type for TimeOfDay validation/format errors. |
src/Period.php |
Renames constructor/factory from of() to from(). |
src/Instant.php |
Updates Duration usage to toSeconds() / fromSeconds(). |
tests/DurationTest.php |
Updates tests for refactored Duration API + adds division test coverage. |
tests/InstantTest.php |
Updates tests for renamed Duration factories/accessors and adjusts test names/descriptions. |
tests/PeriodTest.php |
Updates tests for Period::from() and refactored Duration API. |
tests/DayOfWeekTest.php |
Adds coverage for ISO mapping, weekday/weekend helpers, and derivation from Instant. |
tests/TimeOfDayTest.php |
Adds comprehensive coverage for parsing, validation, formatting, comparisons, and duration computations. |
README.md |
Updates examples for the new Duration/Period APIs and documents DayOfWeek + TimeOfDay. |
Comments suppressed due to low confidence (3)
src/Period.php:33
Period::of()was renamed/removed in favor ofPeriod::from(), which is a public API breaking change for existing consumers. Consider keepingof()as a deprecated wrapper aroundfrom()for at least one release cycle (and update docs accordingly) to ease migration.
public static function from(Instant $from, Instant $to): Period
{
if ($from->isAfterOrEqual(other: $to)) {
src/Duration.php:85
Durationrenamed all factories (ofSeconds/ofMinutes/ofHours/ofDays) tofrom*()and removed the publicsecondsproperty in favor oftoSeconds(). If this library has external consumers, these are API breaking changes; consider adding deprecated aliases (of*()forwarding tofrom*(), and possibly a deprecated accessor forseconds) to preserve backward compatibility during a transition period.
/**
* Creates a Duration from a number of seconds.
*
* @param int $seconds The number of seconds (must be non-negative).
* @return Duration The created Duration.
* @throws InvalidSeconds If the value is negative.
*/
public static function fromSeconds(int $seconds): Duration
{
return new Duration(seconds: Seconds::from(value: $seconds));
}
/**
* Creates a Duration from a number of minutes.
*
* @param int $minutes The number of minutes (must be non-negative).
* @return Duration The created Duration.
* @throws InvalidSeconds If the value is negative.
*/
public static function fromMinutes(int $minutes): Duration
{
return new Duration(seconds: Seconds::from(value: $minutes * self::SECONDS_PER_MINUTE));
}
/**
* Creates a Duration from a number of hours.
*
* @param int $hours The number of hours (must be non-negative).
* @return Duration The created Duration.
* @throws InvalidSeconds If the value is negative.
*/
public static function fromHours(int $hours): Duration
{
return new Duration(seconds: Seconds::from(value: $hours * self::SECONDS_PER_HOUR));
}
/**
* Creates a Duration from a number of days.
*
* @param int $days The number of days (must be non-negative).
* @return Duration The created Duration.
* @throws InvalidSeconds If the value is negative.
*/
public static function fromDays(int $days): Duration
{
return new Duration(seconds: Seconds::from(value: $days * self::SECONDS_PER_DAY));
}
src/Duration.php:84
Duration::fromMinutes/fromHours/fromDays()rely onInvalidSeconds::becauseIsNegative()when inputs are negative, which produces an error message about “Seconds …” even though the caller passed minutes/hours/days. Consider throwing a unit-specific exception/message (or extendingInvalidSecondsto accept context) so the error accurately reflects the argument that was invalid.
/**
* Creates a Duration from a number of minutes.
*
* @param int $minutes The number of minutes (must be non-negative).
* @return Duration The created Duration.
* @throws InvalidSeconds If the value is negative.
*/
public static function fromMinutes(int $minutes): Duration
{
return new Duration(seconds: Seconds::from(value: $minutes * self::SECONDS_PER_MINUTE));
}
/**
* Creates a Duration from a number of hours.
*
* @param int $hours The number of hours (must be non-negative).
* @return Duration The created Duration.
* @throws InvalidSeconds If the value is negative.
*/
public static function fromHours(int $hours): Duration
{
return new Duration(seconds: Seconds::from(value: $hours * self::SECONDS_PER_HOUR));
}
/**
* Creates a Duration from a number of days.
*
* @param int $days The number of days (must be non-negative).
* @return Duration The created Duration.
* @throws InvalidSeconds If the value is negative.
*/
public static function fromDays(int $days): Duration
{
return new Duration(seconds: Seconds::from(value: $days * self::SECONDS_PER_DAY));
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2be66af2d2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
No description provided.