Skip to content

Commit d4fc104

Browse files
authored
Add getDateTime and findDateTime
1 parent 492ca20 commit d4fc104

5 files changed

Lines changed: 199 additions & 3 deletions

File tree

‎.github/workflows/build.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
strategy:
99
matrix:
1010
operating-system: [ ubuntu-latest ]
11-
php-versions: [ '8.2', '8.3', '8.4', '8.5' ]
11+
php-versions: [ '8.4', '8.5' ]
1212
name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
1313

1414
steps:

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ A strictly typed array reader for PHP.
99

1010
## Requirements
1111

12-
* PHP 8.2 - 8.5
12+
* PHP 8.4 - 8.5
1313

1414
## Installation
1515

‎composer.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
],
1414
"homepage": "https://github.com/selective-php/array-reader",
1515
"require": {
16-
"php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
16+
"php": "~8.4.0 || ~8.5.0"
1717
},
1818
"require-dev": {
1919
"cakephp/chronos": "^2 || ^3",

‎src/ArrayReader.php‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Selective\ArrayReader;
44

55
use Cake\Chronos\Chronos;
6+
use DateTimeImmutable;
7+
use DateTimeInterface;
68
use InvalidArgumentException;
79

810
/**
@@ -237,6 +239,46 @@ public function findBool(string $key, ?bool $default = null): ?bool
237239
return (bool)$value;
238240
}
239241

242+
/**
243+
* Get value as DateTimeImmutable.
244+
*
245+
* @param string $key The key
246+
* @param DateTimeImmutable|null $default The default value
247+
*
248+
* @throws InvalidArgumentException
249+
*
250+
* @return DateTimeImmutable The value
251+
*/
252+
public function getDateTime(string $key, ?DateTimeImmutable $default = null): DateTimeImmutable
253+
{
254+
$value = $this->find($key, $default);
255+
256+
if ($this->isNullOrBlank($value)) {
257+
throw new InvalidArgumentException(sprintf('No value found for key "%s"', $key));
258+
}
259+
260+
return $this->toDateTimeImmutable($key, $value);
261+
}
262+
263+
/**
264+
* Get value as DateTimeImmutable or null.
265+
*
266+
* @param string $key The key
267+
* @param DateTimeImmutable|null $default The default value
268+
*
269+
* @return DateTimeImmutable|null The value
270+
*/
271+
public function findDateTime(string $key, ?DateTimeImmutable $default = null): ?DateTimeImmutable
272+
{
273+
$value = $this->find($key, $default);
274+
275+
if ($this->isNullOrBlank($value)) {
276+
return null;
277+
}
278+
279+
return $this->toDateTimeImmutable($key, $value);
280+
}
281+
240282
/**
241283
* Get value as Chronos.
242284
*
@@ -377,4 +419,35 @@ private function isNullOrBlank(mixed $value): bool
377419
{
378420
return $value === null || $value === '';
379421
}
422+
423+
/**
424+
* Cast a value to DateTimeImmutable.
425+
*
426+
* @param string $key The key
427+
* @param mixed $value The value
428+
*
429+
* @throws InvalidArgumentException
430+
*
431+
* @return DateTimeImmutable The date
432+
*/
433+
private function toDateTimeImmutable(string $key, mixed $value): DateTimeImmutable
434+
{
435+
if ($value instanceof DateTimeImmutable) {
436+
return $value;
437+
}
438+
439+
if ($value instanceof DateTimeInterface) {
440+
return DateTimeImmutable::createFromInterface($value);
441+
}
442+
443+
if (is_int($value) || (is_float($value) && is_finite($value))) {
444+
return DateTimeImmutable::createFromTimestamp($value);
445+
}
446+
447+
if (!is_string($value)) {
448+
throw new InvalidArgumentException(sprintf('Invalid date value for key "%s"', $key));
449+
}
450+
451+
return new DateTimeImmutable($value);
452+
}
380453
}

‎tests/ArrayReaderTest.php‎

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace Selective\ArrayReader\Test;
44

5+
use Cake\Chronos\Chronos;
6+
use DateTime;
7+
use DateTimeImmutable;
58
use InvalidArgumentException;
69
use PHPUnit\Framework\Attributes\DataProvider;
710
use PHPUnit\Framework\TestCase;
@@ -429,4 +432,124 @@ public static function providerFindArray(): array
429432
[[['key' => 'value'], ['key2' => 'value2']], 2, null, null],
430433
];
431434
}
435+
436+
/**
437+
* Test.
438+
*
439+
* @param mixed $data The data
440+
* @param string $key The lookup key
441+
* @param mixed $default The default value
442+
* @param mixed $expected The expected value
443+
*
444+
* @return void
445+
*/
446+
#[DataProvider('providerGetDateTime')]
447+
public function testGetDateTime($data, string $key, $default, $expected): void
448+
{
449+
$reader = new ArrayReader($data);
450+
451+
$this->assertEquals($expected, $reader->findDateTime($key, $default));
452+
$this->assertEquals($expected, $reader->getDateTime($key, $default));
453+
}
454+
455+
/**
456+
* Provider.
457+
*
458+
* @return array[] The test data
459+
*/
460+
public static function providerGetDateTime(): array
461+
{
462+
$date = new DateTimeImmutable('2020-01-02T03:04:05+00:00');
463+
$fraction = new DateTimeImmutable('2020-01-02T03:04:05.500000+00:00');
464+
$chronos = new Chronos('2020-01-02T03:04:05+00:00');
465+
466+
return [
467+
[['created' => '2020-01-02T03:04:05+00:00'], 'created', null, $date],
468+
[['created' => $date], 'created', null, $date],
469+
[['created' => new DateTime('2020-01-02T03:04:05+00:00')], 'created', null, $date],
470+
[['created' => 1577934245], 'created', null, $date],
471+
[['created' => 1577934245.5], 'created', null, $fraction],
472+
[['user' => ['created' => '2020-01-02T03:04:05+00:00']], 'user.created', null, $date],
473+
[['created' => $chronos], 'created', null, $chronos],
474+
[[], 'missing', $date, $date],
475+
[['created' => null], 'created', $date, $date],
476+
];
477+
}
478+
479+
/**
480+
* Test.
481+
*
482+
* @param mixed $data The data
483+
* @param string $key The lookup key
484+
* @param mixed $default The default value
485+
*
486+
* @return void
487+
*/
488+
#[DataProvider('providerGetDateTimeError')]
489+
public function testGetDateTimeError($data, string $key, $default): void
490+
{
491+
$reader = new ArrayReader($data);
492+
493+
$this->expectException(InvalidArgumentException::class);
494+
495+
$reader->getDateTime($key, $default);
496+
}
497+
498+
/**
499+
* Provider.
500+
*
501+
* @return array[] The test data
502+
*/
503+
public static function providerGetDateTimeError(): array
504+
{
505+
return [
506+
[['created' => null], 'created', null],
507+
[['created' => ''], 'created', null],
508+
[[], 'missing', null],
509+
[['created' => ['not-a-date']], 'created', null],
510+
[['created' => INF], 'created', null],
511+
[['created' => NAN], 'created', null],
512+
[['user' => ['created' => null]], 'user.created', null],
513+
];
514+
}
515+
516+
/**
517+
* Test.
518+
*
519+
* @param mixed $data The data
520+
* @param string $key The lookup key
521+
* @param mixed $default The default value
522+
* @param mixed $expected The expected value
523+
*
524+
* @return void
525+
*/
526+
#[DataProvider('providerFindDateTime')]
527+
public function testFindDateTime($data, string $key, $default, $expected): void
528+
{
529+
$reader = new ArrayReader($data);
530+
531+
$this->assertEquals($expected, $reader->findDateTime($key, $default));
532+
}
533+
534+
/**
535+
* Provider.
536+
*
537+
* @return array[] The test data
538+
*/
539+
public static function providerFindDateTime(): array
540+
{
541+
$date = new DateTimeImmutable('2020-01-02T03:04:05+00:00');
542+
543+
return [
544+
[['created' => '2020-01-02T03:04:05+00:00'], 'created', null, $date],
545+
[['created' => null], 'created', null, null],
546+
[['created' => ''], 'created', null, null],
547+
[['created' => ''], 'created', $date, null],
548+
[[], 'missing', null, null],
549+
[[], 'missing', $date, $date],
550+
[['created' => null], 'created', $date, $date],
551+
[['user' => ['created' => '2020-01-02T03:04:05+00:00']], 'user.created', null, $date],
552+
[['user' => ['created' => null]], 'user.created', null, null],
553+
];
554+
}
432555
}

0 commit comments

Comments
 (0)