Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/current/2333-time-zone-in-recipe-stubs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Fixed

- Use server time zone for presentation of recipe information
55 changes: 55 additions & 0 deletions lib/Helper/Filter/JSON/TimezoneFixFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace OCA\Cookbook\Helper\Filter\JSON;

use DateTime;
use DateTimeZone;
use Psr\Log\LoggerInterface;

/**
* Fix the timestamp of the dates created and modified for recipe stubs to have a timezone
*
* This expects ISO conforming time data as input
*/
class TimezoneFixFilter extends AbstractJSONFilter {
/** @var LoggerInterface */
private $logger;

public function __construct(LoggerInterface $logger) {
$this->logger = $logger;
}

public function apply(array &$json): bool {
$changed = false;
foreach(['dateCreated', 'dateModified'] as $key) {
if(isset($json[$key]) && $json[$key]) {
$json[$key] = $this->handleTimestamp($json[$key], $changed);
}
}
return $changed;
}

private function handleTimestamp(string $value, bool &$changed): string {
$pattern = '/^([0-9]{4}-[0-9]{2}-[0-9]{2})T([0-9]{1,2}:[0-9]{2}:[0-9]{2}(?:[.,][0-9]+)?)(\+[0-9]{2}:?[0-9]{2})/';
$match = preg_match($pattern, $value, $matches);

if($match == 1) {
return $value;
}

try {
$defaultTimezone = date_default_timezone_get();
} catch (\Exception $ex) {
$this->logger->error('Cannot get the default timezone of server.');
return $value;
}
$serverTimeZone = new DateTimeZone($defaultTimezone);
$now = new DateTime('now', $serverTimeZone);
$offsetSec = $serverTimeZone->getOffset($now);
$offsetHour = $offsetSec / 3600;

$changed = true;
return sprintf('%s%+05d', $value, $offsetHour * 100);
}

}
5 changes: 4 additions & 1 deletion lib/Helper/Filter/Output/RecipeStubFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use OCA\Cookbook\Helper\Filter\JSON\RecipeIdCopyFilter;
use OCA\Cookbook\Helper\Filter\JSON\RecipeIdTypeFilter;
use OCA\Cookbook\Helper\Filter\JSON\TimestampFixFilter;
use OCA\Cookbook\Helper\Filter\JSON\TimezoneFixFilter;

class RecipeStubFilter {
/** @var AbstractJSONFilter[] */
Expand All @@ -14,12 +15,14 @@ class RecipeStubFilter {
public function __construct(
RecipeIdTypeFilter $recipeIdTypeFilter,
RecipeIdCopyFilter $recipeIdCopyFilter,
TimestampFixFilter $timestampFixFilter
TimestampFixFilter $timestampFixFilter,
TimezoneFixFilter $timezoneFixFilter
) {
$this->filters = [
$recipeIdCopyFilter,
$recipeIdTypeFilter,
$timestampFixFilter,
$timezoneFixFilter,
];
}

Expand Down
54 changes: 54 additions & 0 deletions tests/Unit/Helper/Filter/JSON/TimezoneFixFilterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace OCA\Cookbook\tests\Unit\Helper\Filter\JSON;

use DateTime;
use DateTimeZone;
use OCA\Cookbook\Helper\Filter\JSON\TimezoneFixFilter;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;

class TimezoneFixFilterTest extends TestCase {
/** @var TimezoneFixFilter */
private $dut;

public function setUp(): void {
$logger = $this->createStub(LoggerInterface::class);
$this->dut = new TimezoneFixFilter($logger);
}

public function db() {
$defaultTimezone = date_default_timezone_get();
$tz = new DateTimeZone($defaultTimezone);
$now = new DateTime('now', $tz);
$offset = $tz->getOffset($now);
$hours = sprintf('%+03d00', $offset / 3600);

yield ["2024-05-20T10:12:00$hours", "2024-05-20T10:12:00$hours", false];
yield ["2024-05-20T10:12:00", "2024-05-20T10:12:00$hours", true];
yield ["2024-05-20T10:12:00.20$hours", "2024-05-20T10:12:00.20$hours", false];
yield ["2024-05-20T10:12:00.20", "2024-05-20T10:12:00.20$hours", true];
yield ["2024-05-20T1:12:00$hours", "2024-05-20T1:12:00$hours", false];
yield ["2024-05-20T1:12:00", "2024-05-20T1:12:00$hours", true];
}

/** @dataProvider db */
public function testFilter($inputDate, $expectedDate, $changed) {
$input = $this->getStub($inputDate);
$expected = $this->getStub($expectedDate);

$ret = $this->dut->apply($input);

$this->assertEquals($expected, $input);
$this->assertEquals($changed, $ret);
}

private function getStub($date) {
return [
'name' => 'Test Recipe',
'id' => 123,
'dateCreated' => $date,
'dateModified' => $date,
];
}
}