Skip to content

Commit

Permalink
fix(query): DateTime params ignore configured timezone
Browse files Browse the repository at this point in the history
  • Loading branch information
roydejong committed Jan 19, 2023
1 parent ee39fad commit b57a366
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 1 deletion.
5 changes: 5 additions & 0 deletions lib/Database/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ public function __construct(DatabaseConfig $config)
$this->queryLogger = null;
}

public function getConfig(): DatabaseConfig
{
return $this->config;
}

/**
* Sets the query logger on this connection instance.
*
Expand Down
2 changes: 1 addition & 1 deletion lib/Database/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ protected function preProcessParam($paramValue)
if ($paramValue instanceof \DateTime) {
// Format DateTime to database format / UTC
$dt = clone $paramValue;
$dt->setTimezone(new DateTimeZone('UTC'));
$dt->setTimezone(new DateTimeZone($this->connection->getConfig()->timezone));
return $dt->format(Column::DATE_TIME_FORMAT);
}

Expand Down
109 changes: 109 additions & 0 deletions tests/Database/TimezoneTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

namespace Softwarepunt\Instarecord\Tests\Database;

use PHPUnit\Framework\TestCase;
use SoftwarePunt\Instarecord\Instarecord;
use SoftwarePunt\Instarecord\Tests\Samples\User;
use SoftwarePunt\Instarecord\Tests\Testing\TestDatabaseConfig;

class TimezoneTest extends TestCase
{
/**
* @runInSeparateProcess
*/
public function testTimezoneWriteConsistency()
{
if (!date_default_timezone_set("Europe/Amsterdam"))
$this->markTestSkipped('Failed to set default PHP timezone');

Instarecord::config(new TestDatabaseConfig());
Instarecord::config()->timezone = "Europe/Amsterdam";

$jan1st = new \DateTime("2023-01-01 00:00:00");

$user = new User();
$user->userName = "TimeZoneTest";
$user->joinDate = $jan1st;
$user->save();

$userRefetch = User::fetch($user->id);

$this->assertSame(
"2023-01-01 00:00:00",
$userRefetch->joinDate->format('Y-m-d H:i:s')
);
}

/**
* @depends testTimezoneWriteConsistency
* @runInSeparateProcess
*/
public function testTimezoneQueryConsistency()
{
if (!date_default_timezone_set("Europe/Amsterdam"))
$this->markTestSkipped('Failed to set default PHP timezone');

Instarecord::config(new TestDatabaseConfig());
Instarecord::config()->timezone = "Europe/Amsterdam";

$jan1st = new \DateTime("2023-01-01 00:00:00");

$query = User::query()->where('join_date = ?', $jan1st);

$queryString = $query->createStatementText();
$queryParams = $query->getBoundParametersForGeneratedStatement();

$this->assertEquals('SELECT * FROM users WHERE (join_date = ?);', $queryString);
$this->assertEquals('2023-01-01 00:00:00', $queryParams[0],
"Query date/time should automatically adjust to database timezone");
}

/**
* @depends testTimezoneWriteConsistency
* @runInSeparateProcess
*/
public function testTimezoneQueryInconsistency_Up()
{
if (!date_default_timezone_set("UTC"))
$this->markTestSkipped('Failed to set default PHP timezone');

Instarecord::config(new TestDatabaseConfig());
Instarecord::config()->timezone = "Europe/Amsterdam";

$jan1st = new \DateTime("2023-01-01 00:00:00");

$query = User::query()->where('join_date = ?', $jan1st);

$queryString = $query->createStatementText();
$queryParams = $query->getBoundParametersForGeneratedStatement();

$this->assertEquals('SELECT * FROM users WHERE (join_date = ?);', $queryString);
$this->assertEquals('2023-01-01 01:00:00', $queryParams[0],
"Query date/time should automatically adjust to database timezone");
}

/**
* @depends testTimezoneWriteConsistency
* @runInSeparateProcess
*/
public function testTimezoneQueryInconsistency_Down()
{
if (!date_default_timezone_set("Europe/Amsterdam"))
$this->markTestSkipped('Failed to set default PHP timezone');

Instarecord::config(new TestDatabaseConfig());
Instarecord::config()->timezone = "UTC";

$jan1st = new \DateTime("2023-01-01 00:00:00");

$query = User::query()->where('join_date = ?', $jan1st);

$queryString = $query->createStatementText();
$queryParams = $query->getBoundParametersForGeneratedStatement();

$this->assertEquals('SELECT * FROM users WHERE (join_date = ?);', $queryString);
$this->assertEquals('2022-12-31 23:00:00', $queryParams[0],
"Query date/time should automatically adjust to database timezone");
}
}

0 comments on commit b57a366

Please sign in to comment.