Skip to content

Commit 848e244

Browse files
authored
fix: Fixes timezone formatting when inspecting KSUID.
1 parent 10d6a5c commit 848e244

File tree

5 files changed

+66
-18
lines changed

5 files changed

+66
-18
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ $ksuid = Ksuid::inspectFrom(ksuid: '2QzPUGEaAKHhVcQYrqQodbiZat1');
6363

6464
print_r($ksuid); # Array
6565
# (
66-
# [time] => 2023-06-09 23:30:50 +0000 GMT+0000
66+
# [time] => 2023-06-09 20:30:50 -0300 -03
6767
# [payload] => 464932c1194da98e752145d72b8f0aab
6868
# [timestamp] => 286353450
6969
# )

src/Internal/Timestamp.php

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,51 +3,54 @@
33
namespace TinyBlocks\Ksuid\Internal;
44

55
use DateTime;
6+
use DateTimeZone;
67
use TinyBlocks\Encoder\Base62;
78

89
final class Timestamp
910
{
1011
public const EPOCH = 1400000000;
1112

12-
private readonly int $time;
13-
14-
private function __construct(private readonly int $value, private readonly int $epoch)
13+
private function __construct(private readonly int $value)
1514
{
16-
$this->time = $this->value - $this->epoch;
1715
}
1816

1917
public static function from(int $value): Timestamp
2018
{
21-
return new Timestamp(value: $value, epoch: 0);
19+
return new Timestamp(value: $value);
2220
}
2321

2422
public static function fromBytes(string $value): Timestamp
2523
{
2624
$bytes = Base62::decode(value: $value);
2725
$timestamp = substr($bytes, 0, -16);
2826
$timestamp = substr($timestamp, -4);
29-
$timestamp = (array)unpack("Nuint", $timestamp);
27+
$timestamp = (array)unpack('Nuint', $timestamp);
3028

31-
return new Timestamp(value: $timestamp["uint"], epoch: 0);
29+
return new Timestamp(value: $timestamp['uint']);
3230
}
3331

3432
public static function fromAdjustedCurrentTime(): Timestamp
3533
{
36-
return new Timestamp(value: time(), epoch: self::EPOCH);
34+
return new Timestamp(value: time() - self::EPOCH);
3735
}
3836

39-
public static function format(int $timestamp): string
37+
public function getValue(): int
4038
{
41-
return (new DateTime("@$timestamp"))->format('Y-m-d H:i:s O T');
39+
return $this->value;
4240
}
4341

44-
public function getValue(): int
42+
public function getUnixTime(): int
4543
{
46-
return $this->time;
44+
return $this->value + self::EPOCH;
4745
}
4846

49-
public function getUnixTime(): int
47+
public function toUnixTimeFormatted(): string
5048
{
51-
return $this->time + self::EPOCH;
49+
$timezone = new DateTimeZone(timezone: date_default_timezone_get());
50+
51+
return (new DateTime())
52+
->setTimezone(timezone: $timezone)
53+
->setTimestamp(timestamp: $this->getUnixTime())
54+
->format(format: 'Y-m-d H:i:s O T');
5255
}
5356
}

src/Ksuid.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static function inspectFrom(string $ksuid): array
4444
$ksuid = self::fromPayload(value: $ksuid);
4545

4646
return [
47-
'time' => Timestamp::format(timestamp: $ksuid->getUnixTime()),
47+
'time' => $ksuid->timestamp->toUnixTimeFormatted(),
4848
'payload' => $ksuid->getPayload(),
4949
'timestamp' => $ksuid->getTimestamp()
5050
];

tests/Internal/TimestampTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace TinyBlocks\Ksuid\Internal;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
class TimestampTest extends TestCase
8+
{
9+
/**
10+
* @dataProvider providerForTestFormatWithDifferentTimezones
11+
*/
12+
public function testFormatWithDifferentTimezones(string $timezone, string $expected): void
13+
{
14+
$default = date_default_timezone_get();
15+
date_default_timezone_set($timezone);
16+
17+
$timestamp = Timestamp::from(value: 107608047);
18+
19+
$actual = $timestamp->toUnixTimeFormatted();
20+
21+
self::assertEquals($expected, $actual);
22+
23+
date_default_timezone_set($default);
24+
}
25+
26+
public function providerForTestFormatWithDifferentTimezones(): array
27+
{
28+
return [
29+
[
30+
'timezone' => 'America/Sao_Paulo',
31+
'expected' => '2017-10-10 01:00:47 -0300 -03'
32+
],
33+
[
34+
'timezone' => 'America/New_York',
35+
'expected' => '2017-10-10 00:00:47 -0400 EDT'
36+
],
37+
[
38+
'timezone' => 'Europe/London',
39+
'expected' => '2017-10-10 05:00:47 +0100 BST'
40+
]
41+
];
42+
}
43+
}

tests/KsuidTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Exception;
66
use PHPUnit\Framework\TestCase;
77
use TinyBlocks\Ksuid\Internal\Exceptions\InvalidKsuidForInspection;
8+
use TinyBlocks\Ksuid\Internal\Timestamp;
89

910
class KsuidTest extends TestCase
1011
{
@@ -39,6 +40,7 @@ public function testFromTimestamp(): void
3940

4041
/** @Then a KSUID must be generated */
4142
self::assertEquals($value, $ksuid->getTimestamp());
43+
self::assertEquals($value + Timestamp::EPOCH, $ksuid->getUnixTime());
4244
self::assertEquals(20, strlen($ksuid->getBytes()));
4345
self::assertEquals(Ksuid::ENCODED_SIZE, strlen($ksuid->getValue()));
4446
}
@@ -94,15 +96,15 @@ public function providerForTestInspectFrom(): array
9496
[
9597
'ksuid' => '2QzPUGEaAKHhVcQYrqQodbiZat1',
9698
'expected' => [
97-
'time' => '2023-06-09 23:30:50 +0000 GMT+0000',
99+
'time' => '2023-06-09 20:30:50 -0300 -03',
98100
'payload' => '464932c1194da98e752145d72b8f0aab',
99101
'timestamp' => 286353450
100102
]
101103
],
102104
[
103105
'ksuid' => '0ujzPyRiIAffKhBux4PvQdDqMHY',
104106
'expected' => [
105-
'time' => '2017-10-10 04:46:20 +0000 GMT+0000',
107+
'time' => '2017-10-10 01:46:20 -0300 -03',
106108
'payload' => '73fc1aa3b2446246d6e89fcd909e8fe8',
107109
'timestamp' => 107610780
108110
]

0 commit comments

Comments
 (0)