diff --git a/README.md b/README.md index 959fbc0..ff744f4 100644 --- a/README.md +++ b/README.md @@ -38,12 +38,6 @@ $time->isAfter(Time $anotherTime); $time->isAfterOrEqualTo(Time $anotherTime); ``` -#### Conversion - -The `Time` object can be converted to a string with the `toString` method or just casting the object to a -string `(string)$time`. This will output: `14:30:15`. You are also able to show the time without seconds when using the -`format` method. - #### Difference The time object can also be used to calculate the difference between time objects: @@ -102,6 +96,22 @@ $time->roundUp(15, true); // 02:21:45 $time->roundDown(15, true); // 02:21:30 ``` +#### Presentation + +The `Time` object can be presented as a string with the `toString` method or just casting the object to a +string `(string)$time`. This will output: `14:30:15`. + +There are also two other presentations available, the `toNumericalTime` and `toReadableTime`: + +```php +$time = new Time(12, 30, 45); +$time->toNumericalTime(); // 12:50 +$time->toNumericalTime(true); // 12:50:75 + +$time->toReadableTime(); // 12:30 +$time->toReadableTime(true); // 12:30:45 +``` + ### Time collection `Time` objects can be collected in a `TimeCollection`. The `TimeCollection` ca be initiated with: @@ -121,6 +131,12 @@ A `TimeRange` object contains two `Time` objects, a start and end time. The `Tim $timeRange = new TimeRange($time, $anotherTime); ``` +To get the duration of the range, you can get the `Time` object as duration with: + +```php +$timeRange->getRangeDuration(); +``` + #### Comparison The `TimeRange` object makes it easy to compare to a single `Time` or another `TimeRange`. diff --git a/src/Contracts/TimeInterface.php b/src/Contracts/TimeInterface.php index 1a94390..84e5187 100644 --- a/src/Contracts/TimeInterface.php +++ b/src/Contracts/TimeInterface.php @@ -21,10 +21,6 @@ public function isBeforeOrEqualTo(TimeInterface $time): bool; public function isAfter(TimeInterface $time): bool; public function isAfterOrEqualTo(TimeInterface $time): bool; - // Conversion - public function format(bool $showSeconds = false): string; - public function toString(): string; - // Difference public function diff(TimeInterface $time): TimeInterface; public function diffInSeconds(TimeInterface $time): int; @@ -41,4 +37,8 @@ public function roundUp(int $precision = 5, bool $roundSeconds = false): TimeInt public function roundNatural(int $precision = 5, bool $roundSeconds = false): TimeInterface; public function roundDown(int $precision = 5, bool $roundSeconds = false): TimeInterface; + // Presentation + public function toNumericalTime(bool $showSeconds = false): string; + public function toReadableTime(bool $showSeconds = false): string; + public function toString(): string; } diff --git a/src/Contracts/TimeRangeInterface.php b/src/Contracts/TimeRangeInterface.php index b4a92eb..2e28c91 100644 --- a/src/Contracts/TimeRangeInterface.php +++ b/src/Contracts/TimeRangeInterface.php @@ -9,4 +9,5 @@ public function getEnd(): TimeInterface; public function inRange(TimeInterface $time): bool; public function isOverlapping(TimeRangeInterface $timeRange): bool; + public function getRangeDuration(): TimeInterface; } diff --git a/src/Exceptions/TimeException.php b/src/Exceptions/TimeException.php index b74b416..0040393 100644 --- a/src/Exceptions/TimeException.php +++ b/src/Exceptions/TimeException.php @@ -13,13 +13,6 @@ public static function unableToCreateFromString(string $value): self ); } - public static function invalidHours(int $hours): self - { - return new self( - sprintf('Invalid hours provided: `%d`, must be between 0 and 23', $hours) - ); - } - public static function invalidMinutes(int $minutes): self { return new self( diff --git a/src/Time.php b/src/Time.php index 1dc4f31..dc68e71 100644 --- a/src/Time.php +++ b/src/Time.php @@ -6,18 +6,18 @@ use Vdhicts\Time\Exceptions\TimeException; use Vdhicts\Time\Traits\Cloneable; use Vdhicts\Time\Traits\Comparison; -use Vdhicts\Time\Traits\Conversion; use Vdhicts\Time\Traits\Difference; use Vdhicts\Time\Traits\Duration; +use Vdhicts\Time\Traits\Presentable; use Vdhicts\Time\Traits\Rounding; class Time implements TimeInterface { use Cloneable; use Comparison; - use Conversion; use Difference; use Duration; + use Presentable; use Rounding; private int $hours = 0; @@ -39,15 +39,8 @@ public function getHours(): int return $this->hours; } - /** - * @throws TimeException - */ public function setHours(int $hours): self { - if ($hours < 0 || $hours > 23) { - throw TimeException::invalidHours($hours); - } - $this->hours = $hours; return $this; diff --git a/src/TimeRange.php b/src/TimeRange.php index 396efc2..b193405 100644 --- a/src/TimeRange.php +++ b/src/TimeRange.php @@ -50,4 +50,14 @@ public function isOverlapping(Contracts\TimeRangeInterface $timeRange): bool return ($startIsBeforeOrEqualToEnd && $endIsAfterOrEqualToStart); } + + /** + * Returns the time object for the duration of the range. + */ + public function getRangeDuration(): Contracts\TimeInterface + { + return $this + ->start + ->diff($this->end); + } } diff --git a/src/Traits/Conversion.php b/src/Traits/Conversion.php deleted file mode 100644 index a45cd83..0000000 --- a/src/Traits/Conversion.php +++ /dev/null @@ -1,37 +0,0 @@ -getHours(), - $this->getMinutes(), - $this->getSeconds() - ); - } - - return sprintf( - '%02d:%02d', - $this->getHours(), - $this->getMinutes() - ); - } - - public function toString(): string - { - return $this->format(true); - } - - public function __toString(): string - { - return $this->toString(); - } -} diff --git a/src/Traits/Difference.php b/src/Traits/Difference.php index 33bd123..8d5c255 100644 --- a/src/Traits/Difference.php +++ b/src/Traits/Difference.php @@ -3,10 +3,14 @@ namespace Vdhicts\Time\Traits; use Vdhicts\Time\Contracts\TimeInterface; +use Vdhicts\Time\Exceptions\TimeException; use Vdhicts\Time\TimeFactory; trait Difference { + /** + * @throws TimeException + */ public function diff(TimeInterface $time): TimeInterface { return TimeFactory::createFromDurationInSeconds(abs($this->diffInSeconds($time))); diff --git a/src/Traits/Presentable.php b/src/Traits/Presentable.php new file mode 100644 index 0000000..3785e99 --- /dev/null +++ b/src/Traits/Presentable.php @@ -0,0 +1,38 @@ +getHours(); + $minutes = $this->getMinutes(); + $seconds = $this->getSeconds(); + + return $showSeconds + ? sprintf('%02d:%02d:%02d', $hours, $minutes / 60 * 100, $seconds / 60 * 100) + : sprintf('%02d:%02d', $hours, $minutes / 60 * 100); + } + + public function toReadableTime(bool $showSeconds = false): string + { + $hours = $this->getHours(); + $minutes = $this->getMinutes(); + $seconds = $this->getSeconds(); + + return $showSeconds + ? sprintf('%d:%02d:%02d', $hours, $minutes, $seconds) + : sprintf('%d:%02d', $hours, $minutes); + } + + public function toString(): string + { + return $this->toReadableTime(true); + } + + public function __toString(): string + { + return $this->toString(); + } +} diff --git a/src/Traits/Rounding.php b/src/Traits/Rounding.php index 9ee0470..9cba6cd 100644 --- a/src/Traits/Rounding.php +++ b/src/Traits/Rounding.php @@ -4,7 +4,6 @@ use Vdhicts\Time\Contracts\TimeInterface; use Vdhicts\Time\Exceptions\TimeException; -use Vdhicts\Time\Time; use Vdhicts\Time\TimeFactory; trait Rounding diff --git a/tests/Unit/TimeRangeTest.php b/tests/Unit/TimeRangeTest.php index dd74a0a..ddc5bb0 100644 --- a/tests/Unit/TimeRangeTest.php +++ b/tests/Unit/TimeRangeTest.php @@ -65,4 +65,18 @@ public function testRangeOverlapping(): void $this->assertFalse($firstTimeRange->isOverlapping($thirdTimeRange)); $this->assertTrue($secondTimeRange->isOverlapping($thirdTimeRange)); } + + public function testRangeDuration(): void + { + $startTime = new Time(12, 30, 30); + $endTime = new Time(14, 45, 15); + $timeRange = new TimeRange($startTime, $endTime); + + $duration = $timeRange->getRangeDuration(); + + $this->assertInstanceOf(Time::class, $duration); + $this->assertSame(2, $duration->getHours()); + $this->assertSame(14, $duration->getMinutes()); + $this->assertSame(45, $duration->getSeconds()); + } } diff --git a/tests/Unit/TimeTest.php b/tests/Unit/TimeTest.php index dfbd5ac..7d810b6 100644 --- a/tests/Unit/TimeTest.php +++ b/tests/Unit/TimeTest.php @@ -33,13 +33,6 @@ public function testGetters(): void $this->assertSame($seconds, $time->getSeconds()); } - public function testSetHoursException(): void - { - $this->expectException(TimeException::class); - - $time = new Time(30); - } - public function testSetMinutesException(): void { $this->expectException(TimeException::class); @@ -84,18 +77,6 @@ public function testConversion(): void $this->assertSame('14:30:15', (string)$time); } - public function testFormat(): void - { - $hours = 14; - $minutes = 30; - $seconds = 15; - - $time = new Time($hours, $minutes, $seconds); - - $this->assertSame(sprintf('%s:%s', $hours, $minutes), $time->format()); - $this->assertSame(sprintf('%s:%s:%s', $hours, $minutes, $seconds), $time->format(true)); - } - public function testClone(): void { $hours = 14; @@ -130,27 +111,27 @@ public function testRounding(): void { $time = new Time(2, 29, 45); - $this->assertSame('02:30:00', $time->roundNatural()->toString()); - $this->assertSame('02:30:00', $time->roundUp()->toString()); - $this->assertSame('02:25:00', $time->roundDown()->toString()); + $this->assertSame('2:30:00', $time->roundNatural()->toString()); + $this->assertSame('2:30:00', $time->roundUp()->toString()); + $this->assertSame('2:25:00', $time->roundDown()->toString()); $time = new Time(2, 21, 45); - $this->assertSame('02:20:00', $time->roundNatural(10)->toString()); - $this->assertSame('02:30:00', $time->roundUp(10)->toString()); - $this->assertSame('02:20:00', $time->roundDown(10)->toString()); + $this->assertSame('2:20:00', $time->roundNatural(10)->toString()); + $this->assertSame('2:30:00', $time->roundUp(10)->toString()); + $this->assertSame('2:20:00', $time->roundDown(10)->toString()); $time = new Time(2, 21, 59); - $this->assertSame('02:22:00', $time->roundNatural(5, true)->toString()); - $this->assertSame('02:22:00', $time->roundUp(5, true)->toString()); - $this->assertSame('02:21:55', $time->roundDown(5, true)->toString()); + $this->assertSame('2:22:00', $time->roundNatural(5, true)->toString()); + $this->assertSame('2:22:00', $time->roundUp(5, true)->toString()); + $this->assertSame('2:21:55', $time->roundDown(5, true)->toString()); $time = new Time(2, 21, 33); - $this->assertSame('02:21:30', $time->roundNatural(15, true)->toString()); - $this->assertSame('02:21:45', $time->roundUp(15, true)->toString()); - $this->assertSame('02:21:30', $time->roundDown(15, true)->toString()); + $this->assertSame('2:21:30', $time->roundNatural(15, true)->toString()); + $this->assertSame('2:21:45', $time->roundUp(15, true)->toString()); + $this->assertSame('2:21:30', $time->roundDown(15, true)->toString()); } public function testDifference(): void @@ -171,4 +152,20 @@ public function testDifference(): void $this->assertSame(-12600, $timeEnd->diffInSeconds($timeStart)); $this->assertSame(12600, $timeStart->diffInSeconds($timeEnd)); } + + public function testNumerical(): void + { + $time = new Time(10, 30, 45); + + $this->assertSame('10:50:75', $time->toNumericalTime(true)); + $this->assertSame('10:50', $time->toNumericalTime()); + } + + public function testReadable(): void + { + $time = new Time(10, 30, 45); + + $this->assertSame('10:30:45', $time->toReadableTime(true)); + $this->assertSame('10:30', $time->toReadableTime()); + } }