Skip to content

Commit

Permalink
Fix timezones even more (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
edalzell committed Oct 9, 2023
1 parent b6d9fe3 commit 1b9c8dc
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 129 deletions.
208 changes: 104 additions & 104 deletions resources/timezones.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/Day.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ class Day

private CarbonImmutable $date;

public function __construct(array $data, bool $isAllDay = false)
public function __construct(array $data, string $timezone, bool $isAllDay = false)
{
$this->date = CarbonImmutable::parse(Arr::get($data, 'date'));
$this->date = CarbonImmutable::parse(Arr::get($data, 'date'))->shiftTimezone($timezone);
$this->startTime = Arr::get($data, 'start_time');
$this->endTime = Arr::get($data, 'end_time');

Expand Down
16 changes: 13 additions & 3 deletions src/Types/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,17 @@ public function startTime(): string
public function start(): CarbonImmutable
{
return CarbonImmutable::parse($this->start_date)
->shiftTimezone($this->timezone['timezone'])
->setTimeFromTimeString($this->startTime());
}

public function end(): CarbonImmutable
{
return CarbonImmutable::parse($this->start_date)
->shiftTimezone($this->timezone['timezone'])
->setTimeFromTimeString($this->endTime());
}

public function toICalendarEvent(string|CarbonInterface $date): ?ICalendarEvent
{
if (! $this->occursOnDate($date)) {
Expand All @@ -87,6 +95,7 @@ public function toICalendarEvent(string|CarbonInterface $date): ?ICalendarEvent
$immutableDate = $this->toCarbonImmutable($date);

$iCalEvent = ICalendarEvent::create($this->event->title)
->withoutTimezone()
->uniqueIdentifier($this->event->id())
->startsAt($immutableDate->setTimeFromTimeString($this->startTime()))
->endsAt($immutableDate->setTimeFromTimeString($this->endTime()));
Expand Down Expand Up @@ -120,13 +129,14 @@ protected function toCarbonImmutable(string|CarbonInterface $date): CarbonImmuta
{
$carbon = is_string($date) ? Carbon::parse($date) : $date;

return $carbon->timezone($this->timezone['timezone'])->toImmutable();
return $carbon->shiftTimezone($this->timezone['timezone'])->toImmutable();
}

private function collect(array $dates): Collection
{
return collect($dates)
->map(fn (DateTimeInterface $date) => $this->supplement(date: CarbonImmutable::parse($date)))
->filter();
->map(fn (DateTimeInterface $date) => $this->supplement(
date: CarbonImmutable::parse($date, $this->timezone['timezone'])
))->filter();
}
}
10 changes: 7 additions & 3 deletions src/Types/MultiDayEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ public function __construct(Entry $event, private bool $collapseMultiDays)
parent::__construct($event);

$this->days = collect($this->event->days)
->map(fn (Values $day) => new Day($day->all(), $this->isAllDay()));
->map(fn (Values $day) => new Day(
$day->all(),
$this->timezone['timezone'],
$this->isAllDay()
));
}

/**
Expand Down Expand Up @@ -76,7 +80,7 @@ protected function rule(bool $collapseDays = false): RRuleInterface
if ($this->collapseMultiDays) {
return new RRule([
'count' => 1,
'dtstart' => $this->end()->timezone($this->timezone['timezone']),
'dtstart' => $this->end(),
'freq' => RRule::DAILY,
]);
}
Expand All @@ -85,7 +89,7 @@ protected function rule(bool $collapseDays = false): RRuleInterface
new RSet(),
fn (RSet $rset) => $this->days->each(fn (Day $day) => $rset->addRRule([
'count' => 1,
'dtstart' => $day->end()->subSecond()->timezone($this->timezone['timezone']),
'dtstart' => $day->end()->subSecond(),
'freq' => RRule::SECONDLY,
]))
);
Expand Down
13 changes: 3 additions & 10 deletions src/Types/RecurringEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace TransformStudios\Events\Types;

use Carbon\CarbonImmutable;
use Illuminate\Support\Carbon;
use RRule\RRule;
use RRule\RRuleInterface;
Expand All @@ -27,16 +26,16 @@ public function toICalendarEvents(): array
return [
ICalendarEvent::create($this->event->title)
->uniqueIdentifier($this->event->id())
->startsAt($this->start()->timezone($timezone))
->endsAt($this->end()->timezone($timezone))
->startsAt($this->start())
->endsAt($this->end())
->rrule($this->spatieRule()),
];
}

protected function rule(): RRuleInterface
{
$rule = [
'dtstart' => $this->start()->setTimeFromTimeString($this->endTime()),
'dtstart' => $this->end(),
'freq' => $this->frequency(),
'interval' => $this->interval(),
];
Expand All @@ -48,12 +47,6 @@ protected function rule(): RRuleInterface
return new RRule($rule);
}

private function end(): CarbonImmutable
{
return CarbonImmutable::parse($this->start_date)
->setTimeFromTimeString($this->endTime());
}

private function frequency(): int
{
return match ($this->recurrence->value()) {
Expand Down
10 changes: 7 additions & 3 deletions tests/Unit/DayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ public function canGetEndWhenNoEndTime()
'start_time' => '19:00',
];

$day = new Day(data: $dayData);
$day = new Day(data: $dayData, timezone: 'America/Vancouver');

$this->assertEquals(Carbon::parse('2019-11-23')->endOfDay(), $day->end());
$this->assertEquals(
Carbon::parse('2019-11-23')->shiftTimezone('America/Vancouver')->endOfDay(),
$day->end()
);
}

/** @test */
public function hasNoEndTimeWhenNoEndTime()
{
Expand All @@ -28,7 +32,7 @@ public function hasNoEndTimeWhenNoEndTime()
'start_time' => '19:00',
];

$day = new Day(data: $dayData);
$day = new Day(data: $dayData, timezone: 'America/Vancouver');

$this->assertFalse($day->hasEndTime());
}
Expand Down
24 changes: 20 additions & 4 deletions tests/Unit/MultiDayEventsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public function setUp(): void
{
parent::setUp();

Carbon::setTestNowAndTimezone(now(), 'America/Vancouver');


$entry = Entry::make()
->slug('multi-day-event')
->collection('events')
Expand All @@ -45,6 +48,7 @@ public function setUp(): void
'end_time' => '15:00',
],
],
'timezone' => 'America/Vancouver',
]);

$this->event = EventFactory::createFromEntry($entry);
Expand All @@ -64,6 +68,7 @@ public function setUp(): void
'start_time' => '15:00',
],
],
'timezone' => 'America/Vancouver',
]);

$this->noEndTimeEvent = EventFactory::createFromEntry($noEndTimeEntry);
Expand All @@ -80,6 +85,7 @@ public function setUp(): void
'date' => '2019-11-21',
],
],
'timezone' => 'America/Vancouver',
]);
$this->allDayEvent = EventFactory::createFromEntry($allDayEntry);
}
Expand All @@ -98,8 +104,18 @@ public function canCreateMultiDayEvent()
/** @test */
public function canGetStart()
{
$this->assertEquals(Carbon::parse('2019-11-23 19:00'), $this->event->start());
$this->assertEquals(Carbon::parse('2019-11-20 0:00'), $this->allDayEvent->start());
$this->assertEquals(
Carbon::parse('2019-11-23 19:00')->shiftTimezone('America/Vancouver'),
$this->event->start()
);
$this->assertEquals(
Carbon::parse('2019-11-20 0:00')->shiftTimezone('America/Vancouver'),
$this->allDayEvent->start()
);
$this->assertEquals(
Carbon::parse('2019-11-20 0:00')->shiftTimezone('America/Vancouver')->timezone,
$this->event->start()->timezone
);
}

/** @test */
Expand All @@ -112,7 +128,7 @@ public function noOccurrencesIfNowAfterEndDate()
/** @test */
public function canGenerateNextOccurrenceIfBefore()
{
Carbon::setTestNow('2019-11-22');
Carbon::setTestNowAndTimezone('2019-11-22', 'America/Vancouver');

$this->assertEquals(
Carbon::parse('2019-11-23')->setTimeFromTimeString('19:00:00'),
Expand All @@ -127,7 +143,7 @@ public function canGenerateNextOccurrenceIfBefore()
/** @test */
public function canGenerateNextOccurrenceIfDuring()
{
Carbon::setTestNow('2019-11-24 10:00');
Carbon::setTestNowAndTimezone('2019-11-24 10:00', 'America/Vancouver');
$this->assertEquals(
Carbon::parse('2019-11-24')->setTimeFromTimeString('11:00:00'),
$this->event->nextOccurrences()[0]->start
Expand Down
4 changes: 4 additions & 0 deletions tests/Unit/SingleDayEventsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Carbon\CarbonTimeZone;
use Statamic\Facades\Entry;
use TransformStudios\Events\EventFactory;
use TransformStudios\Events\Tests\TestCase;
Expand All @@ -20,6 +21,7 @@ public function canCreateSingleEvent()
'start_date' => Carbon::now()->toDateString(),
'start_time' => '11:00',
'end_time' => '12:00',
'timezone' => 'America/Vancouver',
]);

$event = EventFactory::createFromEntry($entry);
Expand All @@ -28,6 +30,8 @@ public function canCreateSingleEvent()
$this->assertFalse($event->isRecurring());
$this->assertFalse($event->isMultiDay());
$this->assertTrue($event->hasEndTime());
$this->assertEquals(new CarbonTimeZone('America/Vancouver'), $event->start()->timezone);
$this->assertEquals(new CarbonTimeZone('America/Vancouver'), $event->end()->timezone);
}

/** @test */
Expand Down

0 comments on commit 1b9c8dc

Please sign in to comment.