Skip to content

Commit eb9c425

Browse files
committed
refactor: convert dates to timestamps
1 parent 9a90f8e commit eb9c425

File tree

8 files changed

+15
-50
lines changed

8 files changed

+15
-50
lines changed

README.md

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ Naming used here is the same as in ClickHouse docs.
2121

2222
- [Setup](#setup)
2323
- [Logging](#logging)
24-
- [Time Zones](#time-zones)
2524
- [PSR Factories who?](#psr-factories-who)
2625
- [Sync API](#sync-api)
2726
- [Select](#select)
@@ -64,7 +63,6 @@ $clickHouseClient = new PsrClickHouseClient(
6463
),
6564
new LoggerChain(),
6665
[],
67-
new DateTimeZone('UTC')
6866
);
6967
```
7068

@@ -87,25 +85,6 @@ framework:
8785
database: '%clickhouse.database%'
8886
```
8987
90-
### Time Zones
91-
92-
ClickHouse does not have date times with timezones.
93-
Therefore you need to normalize DateTimes' timezones passed as parameters to ensure proper input format.
94-
95-
Following would be inserted as `2020-01-31 01:00:00` into ClickHouse.
96-
97-
```php
98-
new DateTimeImmutable('2020-01-31 01:00:00', new DateTimeZone('Europe/Prague'));
99-
```
100-
101-
If your server uses `UTC`, the value is incorrect for you actually need to insert `2020-01-31 00:00:00`.
102-
103-
Time zone normalization is enabled by passing `DateTimeZone` into `PsrClickHouseClient` constructor.
104-
105-
```php
106-
new PsrClickHouseClient(..., new DateTimeZone('UTC'));
107-
```
108-
10988
### PSR Factories who?
11089
11190
_The library does not implement it's own HTTP.
@@ -218,7 +197,7 @@ This produces `SELECT 'value'` and it can be passed to `ClickHouseClient::select
218197

219198
Supported types are:
220199
- scalars
221-
- DateTimeImmutable (`\DateTime` is not supported because `ValueFormatter` might modify its timezone so it's not considered safe)
200+
- DateTimeInterface
222201
- [Expression](#expression)
223202
- objects implementing `__toString()`
224203

src/Client/PsrClickHouseAsyncClient.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace SimPod\ClickHouseClient\Client;
66

7-
use DateTimeZone;
87
use Exception;
98
use GuzzleHttp\Promise\Create;
109
use GuzzleHttp\Promise\PromiseInterface;
@@ -32,9 +31,8 @@ public function __construct(
3231
private RequestFactory $requestFactory,
3332
private SqlLogger|null $sqlLogger = null,
3433
private array $defaultSettings = [],
35-
DateTimeZone|null $clickHouseTimeZone = null,
3634
) {
37-
$this->sqlFactory = new SqlFactory(new ValueFormatter($clickHouseTimeZone));
35+
$this->sqlFactory = new SqlFactory(new ValueFormatter());
3836
}
3937

4038
/**

src/Client/PsrClickHouseClient.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace SimPod\ClickHouseClient\Client;
66

7-
use DateTimeZone;
87
use InvalidArgumentException;
98
use Psr\Http\Client\ClientExceptionInterface;
109
use Psr\Http\Client\ClientInterface;
@@ -49,9 +48,8 @@ public function __construct(
4948
private RequestFactory $requestFactory,
5049
private SqlLogger|null $sqlLogger = null,
5150
private array $defaultSettings = [],
52-
DateTimeZone|null $clickHouseTimeZone = null,
5351
) {
54-
$this->valueFormatter = new ValueFormatter($clickHouseTimeZone);
52+
$this->valueFormatter = new ValueFormatter();
5553
$this->sqlFactory = new SqlFactory($this->valueFormatter);
5654
}
5755

src/Param/ParamValueConverterRegistry.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,15 @@ private static function decimalConverter(): Closure
267267
private static function dateConverter(): Closure
268268
{
269269
return static fn (DateTimeInterface|string|int|float $value) => $value instanceof DateTimeInterface
270+
// We cannot convert to timestamp yet https://github.com/ClickHouse/ClickHouse/issues/75217
270271
? $value->format('Y-m-d')
271272
: $value;
272273
}
273274

274275
private static function dateTimeConverter(): Closure
275276
{
276277
return static fn (DateTimeInterface|string|int|float $value) => $value instanceof DateTimeInterface
277-
? $value->format('Y-m-d H:i:s')
278+
? $value->getTimestamp()
278279
: $value;
279280
}
280281

src/Sql/ValueFormatter.php

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
namespace SimPod\ClickHouseClient\Sql;
66

77
use BackedEnum;
8-
use DateTimeImmutable;
9-
use DateTimeZone;
8+
use DateTimeInterface;
109
use SimPod\ClickHouseClient\Exception\UnsupportedParamValue;
1110

1211
use function array_key_first;
@@ -26,10 +25,6 @@
2625
/** @internal */
2726
final readonly class ValueFormatter
2827
{
29-
public function __construct(private DateTimeZone|null $dateTimeZone = null)
30-
{
31-
}
32-
3328
/** @throws UnsupportedParamValue */
3429
public function format(mixed $value, string|null $paramName = null, string|null $sql = null): string
3530
{
@@ -66,12 +61,8 @@ public function format(mixed $value, string|null $paramName = null, string|null
6661
: (string) $value->value;
6762
}
6863

69-
if ($value instanceof DateTimeImmutable) {
70-
if ($this->dateTimeZone !== null) {
71-
$value = $value->setTimezone($this->dateTimeZone);
72-
}
73-
74-
return "'" . $value->format('Y-m-d H:i:s') . "'";
64+
if ($value instanceof DateTimeInterface) {
65+
return (string) $value->getTimestamp();
7566
}
7667

7768
if ($value instanceof Expression) {

tests/Client/Http/RequestFactoryTest.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,10 @@ public function testParamParsed(): void
7878
new Psr17Factory(),
7979
);
8080

81-
$now = new DateTimeImmutable();
82-
$nowDate = $now->format('Y-m-d');
81+
$now = new DateTimeImmutable();
8382

8483
$request = $requestFactory->prepareSqlRequest(
85-
'SELECT {p1:String}, {p_2:Date}',
84+
'SELECT {p1:String}, {p_2:DateTime}',
8685
new RequestSettings(
8786
[],
8887
[],
@@ -104,7 +103,7 @@ public function testParamParsed(): void
104103
'Content-Disposition: form-data; name="param_p_2"',
105104
'Content-Length: 10',
106105
'',
107-
$nowDate,
106+
$now->getTimestamp(),
108107
],
109108
),
110109
$body,

tests/Sql/ExpressionFactoryTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace SimPod\ClickHouseClient\Tests\Sql;
66

7-
use DateTimeZone;
87
use PHPUnit\Framework\Attributes\CoversClass;
98
use PHPUnit\Framework\Attributes\DataProvider;
109
use SimPod\ClickHouseClient\Sql\ExpressionFactory;
@@ -18,7 +17,7 @@ final class ExpressionFactoryTest extends TestCaseBase
1817
#[DataProvider('providerTemplateAndValues')]
1918
public function testTemplateAndValues(string $expectedExpressionString, string $template, array $values): void
2019
{
21-
$expressionFactory = new ExpressionFactory(new ValueFormatter(new DateTimeZone('UTC')));
20+
$expressionFactory = new ExpressionFactory(new ValueFormatter());
2221

2322
self::assertSame(
2423
$expectedExpressionString,

tests/Sql/ValueFormatterTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public function testFormat(
2828
): void {
2929
self::assertSame(
3030
$expectedValue,
31-
(new ValueFormatter(new DateTimeZone('UTC')))->format($value, $paramName, $sql),
31+
(new ValueFormatter())->format($value, $paramName, $sql),
3232
);
3333
}
3434

@@ -68,9 +68,9 @@ public static function providerFormat(): iterable
6868
'SELECT * FROM table WHERE (a,b) IN (:tuples)',
6969
];
7070

71-
yield 'DateTimeImmutable' => ["'2020-01-31 01:23:45'", new DateTimeImmutable('2020-01-31 01:23:45')];
71+
yield 'DateTimeImmutable' => ['1580433825', new DateTimeImmutable('2020-01-31 01:23:45')];
7272
yield 'DateTimeImmutable different PHP and ClickHouse timezones' => [
73-
"'2020-01-31 01:23:45'",
73+
'1580433825',
7474
new DateTimeImmutable('2020-01-31 02:23:45', new DateTimeZone('Europe/Prague')),
7575
];
7676

0 commit comments

Comments
 (0)