Skip to content

Commit fd8b4a0

Browse files
authored
Fix wrong value on DateTime values (#24)
1 parent e24d66c commit fd8b4a0

File tree

4 files changed

+77
-3
lines changed

4 files changed

+77
-3
lines changed

src/Cbor/CBOR.php

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Beau\CborPHP\classes\TaggedValue;
88
use Beau\CborPHP\exceptions\CborException;
99
use Brick\Math\BigDecimal;
10+
use DateInterval;
1011
use DateTime;
1112
use DateTimeImmutable;
1213
use DateTimeInterface;
@@ -30,6 +31,28 @@
3031
use Surreal\Cbor\Types\Table;
3132
use Surreal\Cbor\Types\Uuid;
3233

34+
/**
35+
* @throws Exception
36+
*/
37+
function cborCustomDateToDate(array $date): DateTime {
38+
[$seconds, $nanoseconds] = $date;
39+
40+
// Convert nanoseconds to microseconds (PHP's maximum precision)
41+
$microseconds = intval($nanoseconds / 1000);
42+
43+
// Create DateTime directly with microseconds using DateTimeImmutable and format
44+
$formatted = date('Y-m-d H:i:s', $seconds) . '.' . sprintf('%06d', $microseconds);
45+
46+
// Create DateTime object from formatted string
47+
$date = DateTime::createFromFormat('Y-m-d H:i:s.u', $formatted);
48+
49+
if($date === false) {
50+
throw new Exception("Failed to create DateTime from CBOR custom date format");
51+
}
52+
53+
return $date;
54+
}
55+
3356
class CBOR
3457
{
3558
/**
@@ -162,9 +185,7 @@ public static function decode(string $data): mixed
162185
CustomTag::STRING_UUID => Uuid::fromString($tagged->value),
163186
CustomTag::STRING_DECIMAL => BigDecimal::of($tagged->value),
164187

165-
CustomTag::CUSTOM_DATETIME => (new DateTime())
166-
->setTimestamp($tagged->value[0])
167-
->setTime(0, 0, 0, $tagged->value[1]),
188+
CustomTag::CUSTOM_DATETIME => cborCustomDateToDate($tagged->value),
168189

169190
CustomTag::STRING_DURATION => new Duration($tagged->value),
170191
CustomTag::CUSTOM_DURATION => Duration::fromCompact([$tagged->value[0], $tagged->value[1]]),
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace core\functionality;
4+
5+
use DateTime;
6+
use Exception;
7+
use PHPUnit\Framework\TestCase;
8+
use Surreal\Cbor\Types\Record\RecordId;
9+
use Surreal\Surreal;
10+
11+
final class DateTimeTest extends TestCase
12+
{
13+
private function getDb(): Surreal
14+
{
15+
$db = new Surreal();
16+
17+
$db->connect("http://localhost:8000", [
18+
"namespace" => "test",
19+
"database" => "test"
20+
]);
21+
22+
return $db;
23+
}
24+
25+
/**
26+
* @throws Exception
27+
*/
28+
public function testDateTime(): void
29+
{
30+
$db = $this->getDb();
31+
$dateTime = new DateTime("2025-03-31 08:10:38.821000");
32+
33+
[[$record]] = $db->query("SELECT VALUE timestamp FROM dates:1");
34+
35+
$this->assertEquals($dateTime, $record);
36+
}
37+
}

tests/v1/assets/setup.surql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ DEFINE TABLE test
2525
DEFINE TABLE future_test
2626
PERMISSIONS FULL;
2727

28+
DEFINE TABLE dates
29+
PERMISSIONS FULL;
30+
2831
DEFINE TABLE user
2932
PERMISSIONS
3033
FOR select WHERE id = $auth.id;
@@ -45,4 +48,9 @@ CREATE user CONTENT {
4548

4649
DEFINE FUNCTION fn::greet($name: string) {
4750
RETURN "Hello, " + $name + "!";
51+
};
52+
53+
DELETE dates:1;
54+
CREATE dates:1 CONTENT {
55+
timestamp: d'2025-03-31T08:10:38.821Z'
4856
};

tests/v2/assets/setup.surql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ DEFINE TABLE upsert
3131
DEFINE TABLE future_test
3232
PERMISSIONS FULL;
3333

34+
DEFINE TABLE dates
35+
PERMISSIONS FULL;
36+
3437
DEFINE TABLE user
3538
PERMISSIONS
3639
FOR select WHERE id = $auth.id;
@@ -52,4 +55,9 @@ CREATE user CONTENT {
5255

5356
DEFINE FUNCTION fn::greet($name: string) {
5457
RETURN "Hello, " + $name + "!";
58+
};
59+
60+
DELETE dates:1;
61+
CREATE dates:1 CONTENT {
62+
timestamp: d'2025-03-31T08:10:38.821Z'
5563
};

0 commit comments

Comments
 (0)