Skip to content

Commit 19c6732

Browse files
Merge pull request #115 from stephpy/carbon-as-required-dev
Carbon is not mandatory, we can use php DateTime objects
2 parents a608c15 + c5f2d0b commit 19c6732

File tree

5 files changed

+104
-42
lines changed

5 files changed

+104
-42
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ Calendar::create('Laracon Online')
286286

287287
#### Using Carbon
288288

289-
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/):
289+
You can use the popular [Carbon library](https://carbon.nesbot.com/):
290290

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

597597
```php
598598
$entry = TimezoneEntry::create(
599-
TimezoneEntryType::standard(),
599+
TimezoneEntryType::standard(),
600600
new DateTime('16 may 2020 12:00:00'),
601601
'+00:00',
602602
'+02:00'

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
"require": {
2222
"php": "^7.4|^8.0",
2323
"ext-mbstring": "*",
24-
"nesbot/carbon": "^2.63",
2524
"spatie/enum": "^3.11"
2625
},
2726
"require-dev": {
2827
"ext-json": "*",
28+
"nesbot/carbon": "^2.63",
2929
"larapack/dd": "^1.1",
3030
"pestphp/pest": "^1.22",
3131
"spatie/pest-plugin-snapshots": "^1.1",

src/Timezones/TimezoneRangeCollection.php

+26-10
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
namespace Spatie\IcalendarGenerator\Timezones;
44

5-
use Carbon\CarbonImmutable;
5+
use DateTimeImmutable;
66
use DateTimeInterface;
7+
use DateTimeZone;
78
use Exception;
89

910
class TimezoneRangeCollection
@@ -97,30 +98,45 @@ private function addArray(array $entries)
9798

9899
private function addEntry(string $timezone, DateTimeInterface $date)
99100
{
100-
$date = CarbonImmutable::createFromFormat(
101+
$date = DateTimeImmutable::createFromFormat(
101102
DATE_ATOM,
102103
$date->format(DATE_ATOM)
103-
)->setTimezone('UTC');
104+
)->setTimezone(new DateTimeZone('UTC'));
104105

105-
if (! array_key_exists($timezone, $this->ranges)) {
106+
if (!array_key_exists($timezone, $this->ranges)) {
106107
$this->ranges[$timezone] = [
107-
'min' => CarbonImmutable::maxValue(),
108-
'max' => CarbonImmutable::minValue(),
108+
'min' => $this->getMaximumDateTimeImmutable(),
109+
'max' => $this->getMinimumDateTimeImmutable(),
109110
];
110111
}
111112

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

115-
if ($date->lt($minimum)) {
116+
if ($date < $minimum) {
116117
$this->ranges[$timezone]['min'] = $date;
117118
}
118119

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

122-
if ($date->gt($maximum)) {
123+
if ($date > $maximum) {
123124
$this->ranges[$timezone]['max'] = $date;
124125
}
125126
}
127+
128+
protected function getMinimumDateTimeImmutable(): DateTimeImmutable
129+
{
130+
return PHP_INT_SIZE === 4 ?
131+
(new DateTimeImmutable())->setTimestamp(~PHP_INT_MAX) :
132+
(new DateTimeImmutable('0001-01-01 0:0:0'));
133+
}
134+
135+
protected function getMaximumDateTimeImmutable(): DateTimeImmutable
136+
{
137+
return PHP_INT_SIZE === 4 ?
138+
(new DateTimeImmutable())->setTimestamp(PHP_INT_MAX) :
139+
(new DateTimeImmutable('9999-12-31 23:59:59'));
140+
}
141+
126142
}

tests/Components/CalendarTest.php

+44-15
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
use Carbon\Carbon;
44
use Carbon\CarbonImmutable;
5-
use function PHPUnit\Framework\assertEquals;
6-
use function PHPUnit\Framework\assertInstanceOf;
75
use Spatie\IcalendarGenerator\Components\Calendar;
86
use Spatie\IcalendarGenerator\Components\Event;
97
use Spatie\IcalendarGenerator\Components\Timezone;
10-
118
use Spatie\IcalendarGenerator\Tests\PayloadExpectation;
129
use Spatie\IcalendarGenerator\Tests\PropertyExpectation;
1310

11+
use function PHPUnit\Framework\assertEquals;
12+
use function PHPUnit\Framework\assertInstanceOf;
13+
1414
test('it can create a calendar', function () {
1515
$payload = Calendar::create()->resolvePayload();
1616

@@ -143,7 +143,7 @@ function (Event $event) {
143143
->expectParameterValue('VALUE', 'URI');
144144
});
145145

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

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

179-
test('it will automatically add timezone component', function () {
180-
Carbon::setTestNow(new CarbonImmutable('1 august 2020'));
179+
test('it will automatically add multiple timezone components', function () {
180+
$utcEvent = Event::create('An event with UTC timezone')
181+
->startsAt(new DateTimeImmutable('1 january 2019'))
182+
->endsAt(new DateTimeImmutable('1 january 2021'));
183+
184+
$alternativeTimezoneEvent = Event::create('An event with alternative timezone')
185+
->startsAt(new DateTimeImmutable('1 january 2020', new \DateTimeZone('Europe/Brussels')))
186+
->endsAt(new DateTimeImmutable('1 january 2021', new \DateTimeZone('Europe/Brussels')));
187+
188+
$withoutTimezoneEvent = Event::create('An event without timezone')
189+
->withoutTimezone()
190+
->startsAt(new DateTimeImmutable('1 january 1995', new \DateTimeZone('America/New_York')))
191+
->endsAt(new DateTimeImmutable('1 january 2021', new \DateTimeZone('America/New_York')));
192+
193+
$payload = Calendar::create()->event(
194+
[$utcEvent, $alternativeTimezoneEvent, $withoutTimezoneEvent]
195+
)->resolvePayload();
181196

197+
PayloadExpectation::create($payload)
198+
->expectSubComponentCount(5)
199+
->expectSubComponent(0, function (PayloadExpectation $expectation) {
200+
$expectation->expectType('VTIMEZONE')->expectPropertyValue('TZID', 'UTC');
201+
})
202+
->expectSubComponent(1, function (PayloadExpectation $expectation) {
203+
$expectation->expectType('VTIMEZONE')->expectPropertyValue('TZID', 'Europe/Brussels');
204+
})
205+
->expectSubComponentNotInstanceOf(2, Timezone::class)
206+
->expectSubComponentNotInstanceOf(3, Timezone::class)
207+
->expectSubComponentNotInstanceOf(4, Timezone::class);
208+
});
209+
210+
test('it will automatically add timezone component', function () {
182211
$utcEvent = Event::create('An event with UTC timezone')
183-
->createdAt(new CarbonImmutable('1 january 2019'))
184-
->startsAt(new CarbonImmutable('1 january 2019'))
185-
->endsAt(new CarbonImmutable('1 january 2021'));
212+
->createdAt(new DateTimeImmutable('1 january 2019'))
213+
->startsAt(new DateTimeImmutable('1 january 2019'))
214+
->endsAt(new DateTimeImmutable('1 january 2021'));
186215

187216
$alternativeTimezoneEvent = Event::create('An event with alternative timezone')
188-
->createdAt(new CarbonImmutable('1 january 2020', 'Europe/Brussels'))
189-
->startsAt(new CarbonImmutable('1 january 2020', 'Europe/Brussels'))
190-
->endsAt(new CarbonImmutable('1 january 2021', 'Europe/Brussels'));
217+
->createdAt(new DateTimeImmutable('1 january 2020', new \DateTimeZone('Europe/Brussels')))
218+
->startsAt(new DateTimeImmutable('1 january 2020', new \DateTimeZone('Europe/Brussels')))
219+
->endsAt(new DateTimeImmutable('1 january 2021', new \DateTimeZone('Europe/Brussels')));
191220

192221
$negativeOffsetTimezoneEvent = Event::create('An event with a negative timezone offset')
193-
->createdAt(new CarbonImmutable('1 january 2020', 'America/New_York'))
194-
->startsAt(new CarbonImmutable('1 january 2020', 'America/New_York'))
195-
->endsAt(new CarbonImmutable('1 january 2021', 'America/New_York'));
222+
->createdAt(new DateTimeImmutable('1 january 2020', new \DateTimeZone('America/New_York')))
223+
->startsAt(new DateTimeImmutable('1 january 2020', new \DateTimeZone('America/New_York')))
224+
->endsAt(new DateTimeImmutable('1 january 2021', new \DateTimeZone('America/New_York')));
196225

197226
$payload = Calendar::create()->event(
198227
[$utcEvent, $alternativeTimezoneEvent, $negativeOffsetTimezoneEvent]

tests/Timezones/TimezoneRangeCollectionTest.php

+30-13
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
<?php
22

3-
use Carbon\Carbon;
43
use Carbon\CarbonImmutable;
5-
use function PHPUnit\Framework\assertEquals;
64
use Spatie\IcalendarGenerator\Timezones\TimezoneRangeCollection;
7-
85
use Spatie\IcalendarGenerator\ValueObjects\DateTimeValue;
96

10-
beforeEach(function () {
11-
CarbonImmutable::setTestNow('1 august 2020');
12-
});
7+
use function PHPUnit\Framework\assertEquals;
138

14-
test('it can add dates to a range', function () {
9+
test('it can add dates to a range (through Carbon)', function () {
1510
$d = new DateTimeImmutable('1 july 2020');
1611
$b = new DateTimeImmutable('13 august 2020');
1712
$c = new DateTimeImmutable('21 october 2020');
@@ -32,6 +27,28 @@
3227
], $ranges->get());
3328
});
3429

30+
test('it can add dates to a range', function () {
31+
$d = new DateTimeImmutable('1 july 2020');
32+
$b = new DateTimeImmutable('13 august 2020');
33+
$c = new DateTimeImmutable('21 october 2020');
34+
$a = new DateTimeImmutable('16 may 2020');
35+
36+
$ranges = TimezoneRangeCollection::create();
37+
38+
$ranges->add($a);
39+
$ranges->add($b);
40+
$ranges->add($c);
41+
$ranges->add($d);
42+
43+
assertEquals([
44+
'UTC' => [
45+
'min' => new \DateTimeImmutable('16 may 2020'),
46+
'max' => new \DateTimeImmutable('21 october 2020'),
47+
],
48+
], $ranges->get());
49+
});
50+
51+
3552
test('it can have multiple timezones', function () {
3653
$alternativeTimeZone = new DateTimeZone('Europe/Brussels');
3754

@@ -51,21 +68,21 @@
5168

5269
assertEquals([
5370
'Europe/Brussels' => [
54-
'min' => new CarbonImmutable('15 may 2020 22:00:00'), // UTC transformation
55-
'max' => new CarbonImmutable('20 october 2020 22:00:00'), // UTC transformation
71+
'min' => new \DateTimeImmutable('15 may 2020 22:00:00'), // UTC transformation
72+
'max' => new \DateTimeImmutable('20 october 2020 22:00:00'), // UTC transformation
5673
],
5774
'UTC' => [
58-
'min' => new CarbonImmutable('16 may 2020'),
59-
'max' => new CarbonImmutable('21 october 2020'),
75+
'min' => new \DateTimeImmutable('16 may 2020'),
76+
'max' => new \DateTimeImmutable('21 october 2020'),
6077
],
6178
], $ranges->get());
6279
});
6380

6481
test('it can add different types of date times', function () {
6582
$d = new DateTime('1 july 2020');
6683
$b = new DateTimeImmutable('13 august 2020');
67-
$c = new CarbonImmutable('21 october 2020');
68-
$a = new Carbon('16 may 2020');
84+
$c = new \DateTimeImmutable('21 october 2020');
85+
$a = new \DateTime('16 may 2020');
6986

7087
$ranges = TimezoneRangeCollection::create();
7188

0 commit comments

Comments
 (0)