Skip to content

Commit

Permalink
Merge pull request #144 from spatie/feature/issue-139-diff-methods
Browse files Browse the repository at this point in the history
Fix #139 Add diff methods
  • Loading branch information
kylekatarnls authored Jun 19, 2020
2 parents dd8c0b1 + 1a970b4 commit d4f158d
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea
build
composer.lock
coverage
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,38 @@ Returns previous close DateTime from the given DateTime
$openingHours->nextClose(new DateTime('2016-12-24 11:00:00'));
```

#### `OpeningHours::diffInOpenHours(DateTimeInterface $startDate, DateTimeInterface $endDate) : float`

Return the amount of open time (number of hours as a floating number) between 2 dates/times.

```php
$openingHours->diffInOpenHours(new DateTime('2016-12-24 11:00:00'), new DateTime('2016-12-24 16:34:25'));
```

#### `OpeningHours::diffInOpenMinutes(DateTimeInterface $startDate, DateTimeInterface $endDate) : float`

Return the amount of open time (number of minutes as a floating number) between 2 dates/times.

#### `OpeningHours::diffInOpenSeconds(DateTimeInterface $startDate, DateTimeInterface $endDate) : float`

Return the amount of open time (number of seconds as a floating number) between 2 dates/times.

#### `OpeningHours::diffInClosedHours(DateTimeInterface $startDate, DateTimeInterface $endDate) : float`

Return the amount of closed time (number of hours as a floating number) between 2 dates/times.

```php
$openingHours->diffInClosedHours(new DateTime('2016-12-24 11:00:00'), new DateTime('2016-12-24 16:34:25'));
```

#### `OpeningHours::diffInClosedMinutes(DateTimeInterface $startDate, DateTimeInterface $endDate) : float`

Return the amount of closed time (number of minutes as a floating number) between 2 dates/times.

#### `OpeningHours::diffInClosedSeconds(DateTimeInterface $startDate, DateTimeInterface $endDate) : float`

Return the amount of closed time (number of seconds as a floating number) between 2 dates/times.

#### `OpeningHours::currentOpenRange(DateTimeInterface $dateTime) : false | TimeRange`

Returns a `Spatie\OpeningHours\TimeRange` instance of the current open range if the
Expand Down
110 changes: 110 additions & 0 deletions src/Helpers/DiffTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

namespace Spatie\OpeningHours\Helpers;

use DateTimeInterface;

trait DiffTrait
{
private function diffInSeconds(string $stateCheckMethod, string $nextDateMethod, string $skipDateMethod, DateTimeInterface $startDate, DateTimeInterface $endDate): float
{
$time = 0;

if ($endDate < $startDate) {
return -$this->diffInSeconds($stateCheckMethod, $nextDateMethod, $skipDateMethod, $endDate, $startDate);
}

$date = $startDate;

while ($date < $endDate) {
if ($this->$stateCheckMethod($date)) {
$date = $this->$skipDateMethod($date);
continue;
}

$nextDate = min($endDate, $this->$nextDateMethod($date));
$time += floatval($nextDate->format('U.u')) - floatval($date->format('U.u'));
$date = $nextDate;
}

return $time;
}

/**
* Return the amount of open time (number of seconds as a floating number) between 2 dates/times.
*
* @param DateTimeInterface $startDate
* @param DateTimeInterface $endDate
*
* @return float
*/
public function diffInOpenSeconds(DateTimeInterface $startDate, DateTimeInterface $endDate): float
{
return $this->diffInSeconds('isClosedAt', 'nextClose', 'nextOpen', $startDate, $endDate);
}

/**
* Return the amount of open time (number of minutes as a floating number) between 2 dates/times.
*
* @param DateTimeInterface $startDate
* @param DateTimeInterface $endDate
*
* @return float
*/
public function diffInOpenMinutes(DateTimeInterface $startDate, DateTimeInterface $endDate): float
{
return $this->diffInOpenSeconds($startDate, $endDate) / 60;
}

/**
* Return the amount of open time (number of hours as a floating number) between 2 dates/times.
*
* @param DateTimeInterface $startDate
* @param DateTimeInterface $endDate
*
* @return float
*/
public function diffInOpenHours(DateTimeInterface $startDate, DateTimeInterface $endDate): float
{
return $this->diffInOpenMinutes($startDate, $endDate) / 60;
}

/**
* Return the amount of closed time (number of seconds as a floating number) between 2 dates/times.
*
* @param DateTimeInterface $startDate
* @param DateTimeInterface $endDate
*
* @return float
*/
public function diffInClosedSeconds(DateTimeInterface $startDate, DateTimeInterface $endDate): float
{
return $this->diffInSeconds('isOpenAt', 'nextOpen', 'nextClose', $startDate, $endDate);
}

/**
* Return the amount of closed time (number of minutes as a floating number) between 2 dates/times.
*
* @param DateTimeInterface $startDate
* @param DateTimeInterface $endDate
*
* @return float
*/
public function diffInClosedMinutes(DateTimeInterface $startDate, DateTimeInterface $endDate): float
{
return $this->diffInClosedSeconds($startDate, $endDate) / 60;
}

/**
* Return the amount of closed time (number of hours as a floating number) between 2 dates/times.
*
* @param DateTimeInterface $startDate
* @param DateTimeInterface $endDate
*
* @return float
*/
public function diffInClosedHours(DateTimeInterface $startDate, DateTimeInterface $endDate): float
{
return $this->diffInClosedMinutes($startDate, $endDate) / 60;
}
}
3 changes: 2 additions & 1 deletion src/OpeningHours.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
use Spatie\OpeningHours\Helpers\Arr;
use Spatie\OpeningHours\Helpers\DataTrait;
use Spatie\OpeningHours\Helpers\DateTimeCopier;
use Spatie\OpeningHours\Helpers\DiffTrait;

class OpeningHours
{
const DEFAULT_DAY_LIMIT = 8;

use DataTrait, DateTimeCopier;
use DataTrait, DateTimeCopier, DiffTrait;

/** @var \Spatie\OpeningHours\Day[] */
protected $openingHours = [];
Expand Down
29 changes: 29 additions & 0 deletions tests/OpeningHoursTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1326,4 +1326,33 @@ public function it_should_support_empty_arrays_with_merge()

$this->assertTrue($hours->isClosedAt(new DateTimeImmutable('2020-01-01')));
}

/** @test */
public function it_can_calculate_time_diff()
{
$openingHours = OpeningHours::create([
'monday' => ['10:00-16:00', '19:30-20:30'],
'tuesday' => ['22:30-04:00'],
'wednesday' => ['07:00-10:00'],
'thursday' => ['09:00-12:00'],
'friday' => ['09:00-12:00'],
'saturday' => [],
'sunday' => [],
]);

$this->assertSame(2.0, $openingHours->diffInClosedSeconds(new DateTimeImmutable('Monday 09:59:58'), new DateTimeImmutable('Monday 10:59:58')));
$this->assertSame(3600.0 - 2.0, $openingHours->diffInOpenSeconds(new DateTimeImmutable('Monday 09:59:58'), new DateTimeImmutable('Monday 10:59:58')));

if (version_compare(PHP_VERSION, '7.1.0-dev', '>=')) {
$this->assertSame(1.5, $openingHours->diffInClosedSeconds(new DateTimeImmutable('Monday 09:59:58.5'), new DateTimeImmutable('Monday 10:59:58.5')));
$this->assertSame(3600.0 - 1.5, $openingHours->diffInOpenSeconds(new DateTimeImmutable('Monday 09:59:58.5'), new DateTimeImmutable('Monday 10:59:58.5')));
}

$this->assertSame(1.5 * 60, $openingHours->diffInOpenMinutes(new DateTimeImmutable('Monday 3pm'), new DateTimeImmutable('Monday 8pm')));
$this->assertSame(3.5 * 60, $openingHours->diffInClosedMinutes(new DateTimeImmutable('Monday 3pm'), new DateTimeImmutable('Monday 8pm')));
$this->assertSame(18.5, $openingHours->diffInOpenHours(new DateTimeImmutable('2020-06-21 3pm'), new DateTimeImmutable('2020-06-25 2pm')));
$this->assertSame(76.5, $openingHours->diffInClosedHours(new DateTimeImmutable('2020-06-21 3pm'), new DateTimeImmutable('2020-06-25 2pm')));
$this->assertSame(-18.5, $openingHours->diffInOpenHours(new DateTimeImmutable('2020-06-25 2pm'), new DateTimeImmutable('2020-06-21 3pm')));
$this->assertSame(-76.5, $openingHours->diffInClosedHours(new DateTimeImmutable('2020-06-25 2pm'), new DateTimeImmutable('2020-06-21 3pm')));
}
}

0 comments on commit d4f158d

Please sign in to comment.