Skip to content

Commit

Permalink
Carbon is not mandatory, we can use php DateTime objects
Browse files Browse the repository at this point in the history
  • Loading branch information
stephpy committed Dec 21, 2023
1 parent a608c15 commit 07586cb
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 44 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ Calendar::create('Laracon Online')

#### Using Carbon

Since this package expects a DateTimeInterface for properties related to date and time, it is possible to use the popular [Carbon library](https://carbon.nesbot.com/):
You can use the popular [Carbon library](https://carbon.nesbot.com/):

``` php
use Carbon\Carbon;
Expand Down Expand Up @@ -381,7 +381,7 @@ Or trigger an alert on a specific date:
``` php
Event::create('Laracon Online')
->alertAt(
new DateTime('05/16/2020 12:00:00'),
new DateTime('05/16/2020 12:00:00'),
'Laracon online has ended, see you next year!'
);
```
Expand Down Expand Up @@ -596,7 +596,7 @@ A timezone consists of multiple entries where the time of the timezone changed r

```php
$entry = TimezoneEntry::create(
TimezoneEntryType::standard(),
TimezoneEntryType::standard(),
new DateTime('16 may 2020 12:00:00'),
'+00:00',
'+02:00'
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
"require": {
"php": "^7.4|^8.0",
"ext-mbstring": "*",
"nesbot/carbon": "^2.63",
"spatie/enum": "^3.11"
},
"require-dev": {
"ext-json": "*",
"nesbot/carbon": "^2.63",
"larapack/dd": "^1.1",
"pestphp/pest": "^1.22",
"spatie/pest-plugin-snapshots": "^1.1",
Expand Down
34 changes: 24 additions & 10 deletions src/Timezones/TimezoneRangeCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Spatie\IcalendarGenerator\Timezones;

use Carbon\CarbonImmutable;
use DateTimeInterface;
use Exception;

Expand Down Expand Up @@ -97,30 +96,45 @@ private function addArray(array $entries)

private function addEntry(string $timezone, DateTimeInterface $date)
{
$date = CarbonImmutable::createFromFormat(
$date = \DateTimeImmutable::createFromFormat(
DATE_ATOM,
$date->format(DATE_ATOM)
)->setTimezone('UTC');
)->setTimezone(new \DateTimeZone('UTC'));

if (! array_key_exists($timezone, $this->ranges)) {
if (!array_key_exists($timezone, $this->ranges)) {
$this->ranges[$timezone] = [
'min' => CarbonImmutable::maxValue(),
'max' => CarbonImmutable::minValue(),
'min' => $this->getMaximumDateTimeImmutable(),
'max' => $this->getMinimumDateTimeImmutable(),
];
}

/** @var \Carbon\CarbonImmutable $minimum */
/** @var \DateTimeInterface $minimum */
$minimum = $this->ranges[$timezone]['min'];

if ($date->lt($minimum)) {
if ($date < $minimum) {
$this->ranges[$timezone]['min'] = $date;
}

/** @var \Carbon\CarbonImmutable $maximum */
/** @var \DateTimeInterface $maximum */
$maximum = $this->ranges[$timezone]['max'];

if ($date->gt($maximum)) {
if ($date > $maximum) {
$this->ranges[$timezone]['max'] = $date;
}
}

private function getMinimumDateTimeImmutable(): \DateTimeImmutable
{
return PHP_INT_SIZE === 4 ?
(new \DateTimeImmutable())->setTimestamp(~PHP_INT_MAX) :
(new \DateTimeImmutable('0001-01-01 0:0:0'));
}

private function getMaximumDateTimeImmutable(): \DateTimeImmutable
{
return PHP_INT_SIZE === 4 ?
(new \DateTimeImmutable())->setTimestamp(PHP_INT_MAX) :
(new \DateTimeImmutable('9999-12-31 23:59:59'));
}

}
59 changes: 44 additions & 15 deletions tests/Components/CalendarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

use Carbon\Carbon;
use Carbon\CarbonImmutable;
use function PHPUnit\Framework\assertEquals;
use function PHPUnit\Framework\assertInstanceOf;
use Spatie\IcalendarGenerator\Components\Calendar;
use Spatie\IcalendarGenerator\Components\Event;
use Spatie\IcalendarGenerator\Components\Timezone;

use Spatie\IcalendarGenerator\Tests\PayloadExpectation;
use Spatie\IcalendarGenerator\Tests\PropertyExpectation;

use function PHPUnit\Framework\assertEquals;
use function PHPUnit\Framework\assertInstanceOf;

test('it can create a calendar', function () {
$payload = Calendar::create()->resolvePayload();

Expand Down Expand Up @@ -143,7 +143,7 @@ function (Event $event) {
->expectParameterValue('VALUE', 'URI');
});

test('it will automatically add multiple timezone components', function () {
test('it will automatically add multiple timezone components (through Carbon)', function () {
Carbon::setTestNow(new CarbonImmutable('1 august 2020'));

$utcEvent = Event::create('An event with UTC timezone')
Expand Down Expand Up @@ -176,23 +176,52 @@ function (Event $event) {
->expectSubComponentNotInstanceOf(4, Timezone::class);
});

test('it will automatically add timezone component', function () {
Carbon::setTestNow(new CarbonImmutable('1 august 2020'));
test('it will automatically add multiple timezone components', function () {
$utcEvent = Event::create('An event with UTC timezone')
->startsAt(new DateTimeImmutable('1 january 2019'))
->endsAt(new DateTimeImmutable('1 january 2021'));

$alternativeTimezoneEvent = Event::create('An event with alternative timezone')
->startsAt(new DateTimeImmutable('1 january 2020', new \DateTimeZone('Europe/Brussels')))
->endsAt(new DateTimeImmutable('1 january 2021', new \DateTimeZone('Europe/Brussels')));

$withoutTimezoneEvent = Event::create('An event without timezone')
->withoutTimezone()
->startsAt(new DateTimeImmutable('1 january 1995', new \DateTimeZone('America/New_York')))
->endsAt(new DateTimeImmutable('1 january 2021', new \DateTimeZone('America/New_York')));

$payload = Calendar::create()->event(
[$utcEvent, $alternativeTimezoneEvent, $withoutTimezoneEvent]
)->resolvePayload();

PayloadExpectation::create($payload)
->expectSubComponentCount(5)
->expectSubComponent(0, function (PayloadExpectation $expectation) {
$expectation->expectType('VTIMEZONE')->expectPropertyValue('TZID', 'UTC');
})
->expectSubComponent(1, function (PayloadExpectation $expectation) {
$expectation->expectType('VTIMEZONE')->expectPropertyValue('TZID', 'Europe/Brussels');
})
->expectSubComponentNotInstanceOf(2, Timezone::class)
->expectSubComponentNotInstanceOf(3, Timezone::class)
->expectSubComponentNotInstanceOf(4, Timezone::class);
});

test('it will automatically add timezone component', function () {
$utcEvent = Event::create('An event with UTC timezone')
->createdAt(new CarbonImmutable('1 january 2019'))
->startsAt(new CarbonImmutable('1 january 2019'))
->endsAt(new CarbonImmutable('1 january 2021'));
->createdAt(new DateTimeImmutable('1 january 2019'))
->startsAt(new DateTimeImmutable('1 january 2019'))
->endsAt(new DateTimeImmutable('1 january 2021'));

$alternativeTimezoneEvent = Event::create('An event with alternative timezone')
->createdAt(new CarbonImmutable('1 january 2020', 'Europe/Brussels'))
->startsAt(new CarbonImmutable('1 january 2020', 'Europe/Brussels'))
->endsAt(new CarbonImmutable('1 january 2021', 'Europe/Brussels'));
->createdAt(new DateTimeImmutable('1 january 2020', new \DateTimeZone('Europe/Brussels')))
->startsAt(new DateTimeImmutable('1 january 2020', new \DateTimeZone('Europe/Brussels')))
->endsAt(new DateTimeImmutable('1 january 2021', new \DateTimeZone('Europe/Brussels')));

$negativeOffsetTimezoneEvent = Event::create('An event with a negative timezone offset')
->createdAt(new CarbonImmutable('1 january 2020', 'America/New_York'))
->startsAt(new CarbonImmutable('1 january 2020', 'America/New_York'))
->endsAt(new CarbonImmutable('1 january 2021', 'America/New_York'));
->createdAt(new DateTimeImmutable('1 january 2020', new \DateTimeZone('America/New_York')))
->startsAt(new DateTimeImmutable('1 january 2020', new \DateTimeZone('America/New_York')))
->endsAt(new DateTimeImmutable('1 january 2021', new \DateTimeZone('America/New_York')));

$payload = Calendar::create()->event(
[$utcEvent, $alternativeTimezoneEvent, $negativeOffsetTimezoneEvent]
Expand Down
24 changes: 9 additions & 15 deletions tests/Timezones/TimezoneRangeCollectionTest.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
<?php

use Carbon\Carbon;
use Carbon\CarbonImmutable;
use function PHPUnit\Framework\assertEquals;
use Spatie\IcalendarGenerator\Timezones\TimezoneRangeCollection;

use Spatie\IcalendarGenerator\ValueObjects\DateTimeValue;

beforeEach(function () {
CarbonImmutable::setTestNow('1 august 2020');
});
use function PHPUnit\Framework\assertEquals;

test('it can add dates to a range', function () {
$d = new DateTimeImmutable('1 july 2020');
Expand All @@ -26,8 +20,8 @@

assertEquals([
'UTC' => [
'min' => new CarbonImmutable('16 may 2020'),
'max' => new CarbonImmutable('21 october 2020'),
'min' => new \DateTimeImmutable('16 may 2020'),
'max' => new \DateTimeImmutable('21 october 2020'),
],
], $ranges->get());
});
Expand All @@ -51,21 +45,21 @@

assertEquals([
'Europe/Brussels' => [
'min' => new CarbonImmutable('15 may 2020 22:00:00'), // UTC transformation
'max' => new CarbonImmutable('20 october 2020 22:00:00'), // UTC transformation
'min' => new \DateTimeImmutable('15 may 2020 22:00:00'), // UTC transformation
'max' => new \DateTimeImmutable('20 october 2020 22:00:00'), // UTC transformation
],
'UTC' => [
'min' => new CarbonImmutable('16 may 2020'),
'max' => new CarbonImmutable('21 october 2020'),
'min' => new \DateTimeImmutable('16 may 2020'),
'max' => new \DateTimeImmutable('21 october 2020'),
],
], $ranges->get());
});

test('it can add different types of date times', function () {
$d = new DateTime('1 july 2020');
$b = new DateTimeImmutable('13 august 2020');
$c = new CarbonImmutable('21 october 2020');
$a = new Carbon('16 may 2020');
$c = new \DateTimeImmutable('21 october 2020');
$a = new \DateTime('16 may 2020');

$ranges = TimezoneRangeCollection::create();

Expand Down

0 comments on commit 07586cb

Please sign in to comment.