Skip to content

Commit 7730153

Browse files
committed
better support rfc3339
Additional support for microsecond values greater than 6 digits. Signed-off-by: John Laswell <[email protected]>
1 parent f2e22c6 commit 7730153

File tree

4 files changed

+26
-16
lines changed

4 files changed

+26
-16
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.phpunit.cache
2+
.phpunit.result.cache
23

34
composer.lock
45
phpcs.xml

phpunit.xml.dist

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd" beStrictAboutOutputDuringTests="true" bootstrap="vendor/autoload.php" executionOrder="depends,defects" failOnRisky="true" failOnWarning="true">
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd" beStrictAboutOutputDuringTests="true" bootstrap="vendor/autoload.php" executionOrder="depends,defects" failOnRisky="true" failOnWarning="true">
33
<testsuites>
44
<testsuite name="Unit Test Suite">
55
<directory suffix="Test.php">tests/Unit</directory>
66
</testsuite>
77
</testsuites>
8-
<coverage>
8+
<coverage/>
9+
<source>
910
<include>
1011
<directory suffix=".php">src</directory>
1112
</include>
12-
</coverage>
13+
</source>
1314
</phpunit>

src/Utilities/TimeFormatter.php

+13-12
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ final class TimeFormatter
1616
private const TIME_FORMAT = 'Y-m-d\TH:i:s\Z';
1717
private const TIME_ZONE = 'UTC';
1818

19-
private const RFC3339_FORMAT = 'Y-m-d\TH:i:sP';
20-
private const RFC3339_EXTENDED_FORMAT = 'Y-m-d\TH:i:s.uP';
21-
2219
public static function encode(?DateTimeImmutable $time): ?string
2320
{
2421
if ($time === null) {
@@ -34,19 +31,23 @@ public static function decode(?string $time): ?DateTimeImmutable
3431
return null;
3532
}
3633

37-
/** @psalm-suppress UndefinedFunction */
38-
$decoded = DateTimeImmutable::createFromFormat(
39-
\str_contains($time, '.') ? self::RFC3339_EXTENDED_FORMAT : self::RFC3339_FORMAT,
40-
\strtoupper($time),
41-
new DateTimeZone(self::TIME_ZONE)
42-
);
43-
44-
if ($decoded === false) {
34+
try {
35+
$decoded = new DateTimeImmutable($time);
36+
} catch (\Throwable $th) {
4537
throw new ValueError(
4638
\sprintf('%s(): Argument #1 ($time) is not a valid RFC3339 timestamp', __METHOD__)
4739
);
4840
}
4941

50-
return $decoded;
42+
return self::shiftWithTimezone($time, $decoded);
43+
}
44+
45+
private static function shiftWithTimezone(string $time, DateTimeImmutable $datetime): DateTimeImmutable
46+
{
47+
if (strpos($time, '+') === false && strpos($time, '-') === false && strtoupper(substr($time, -1)) !== 'Z') {
48+
return $datetime->setTimezone(new \DateTimeZone('UTC'));
49+
}
50+
51+
return $datetime;
5152
}
5253
}

tests/Unit/Utilities/TimeFormatterTest.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public function testEncode(): void
1919
);
2020
}
2121

22-
public function providesDecodeCases(): array
22+
public static function providesDecodeCases(): array
2323
{
2424
return [
2525
// UTC
@@ -36,6 +36,9 @@ public function providesDecodeCases(): array
3636
['1985-04-12T23:20:50.123450Z', '1985-04-12T23:20:50.12345Z'],
3737
['1985-04-12T23:20:50.123450Z', '1985-04-12T23:20:50.123450Z'],
3838
['1985-04-12T23:20:50.123456Z', '1985-04-12T23:20:50.123456Z'],
39+
['1985-04-12T23:20:50.123456Z', '1985-04-12T23:20:50.1234567Z'],
40+
['1985-04-12T23:20:50.123456Z', '1985-04-12T23:20:50.12345678Z'],
41+
['1985-04-12T23:20:50.123456Z', '1985-04-12T23:20:50.123456789Z'],
3942

4043
// +01:00
4144
['2018-04-05T16:31:00Z', '2018-04-05T17:31:00+01:00'],
@@ -51,6 +54,10 @@ public function providesDecodeCases(): array
5154
['1985-04-12T22:20:50.123450Z', '1985-04-12T23:20:50.12345+01:00'],
5255
['1985-04-12T22:20:50.123450Z', '1985-04-12T23:20:50.123450+01:00'],
5356
['1985-04-12T22:20:50.123456Z', '1985-04-12T23:20:50.123456+01:00'],
57+
['1985-04-12T22:20:50.123456Z', '1985-04-12T23:20:50.1234567+01:00'],
58+
['1985-04-12T22:20:50.123456Z', '1985-04-12T23:20:50.12345678+01:00'],
59+
['1985-04-12T22:20:50.123456Z', '1985-04-12T23:20:50.123456789+01:00'],
60+
['1985-04-12T22:20:50.123456Z', '1985-04-12T23:20:50.1234567890+01:00'],
5461
];
5562
}
5663

0 commit comments

Comments
 (0)