php mssql datatime,php sql datetime时区问题

我正在更新一个与php 7一起工作的项目。在通过sqlsrv驱动程序使用sql server时遇到了日期比较问题。

以前(php 5),当我传递一个php datetime对象作为查询参数时,它与datetime(sql)列的值进行比较,不包括时区。现在考虑到了时区,这就中断了脚本的工作。如何使它不再被计算?不建议将php时区更改为utc或在每个请求中添加“cast to datetime”。

SQL表db.dbo.table内容:

id dt (datetime)

1 2019-08-31 23:59:00.000

php代码

$sqlc = sqlsrv_connect( $serverName,

[

'Database'=>$dbName,

'UID'=>$userName,

'PWD'=>$userPassword,

'CharacterSet' =>'UTF-8',

'ConnectionPooling' => 1

]);

// date with server timezone (local)

$dtObject = date_create('2019-08-31 23:59:00');

// just for example, we are looking for id by known date

$request = "SELECT [id] FROM DB.dbo.TABLE WHERE [dt] = (?)";

$params = [$dtObject];

$query = sqlsrv_query($sqlc, $request, $params, array("Scrollable"=>"forward"));

if ( $query )

{

while( $row = @sqlsrv_fetch_array($query, SQLSRV_FETCH_ASSOC) )

{

// output id

echo "id {$row['id']}\r\n";

}

}

?>

上面的代码对

PHP5.5

,

MSSQL2005

,

php_sqlsrv 3.1.0.0

并返回期望的结果

id : 1

不分时区

PHP DateTime

反对。

但说到

PHP7.3

,

MSSQL2017

php_sqlsrv 5.6.1.11919

,将考虑时区,因此日期不匹配

我认为这是由于

php日期时间

反对

SQL datetimeoffset

,而之前的日期是

SQL datetime

类型。有人知道如何通过避免直接在php代码中进行更改来解决这个问题吗(有很多这样的更改)?

编辑:

为了澄清这种情况,我将给出一些停止正常工作的代码示例

// get date by id (reminder: date stored as datetime)

$request = "SELECT [dt] FROM DB.dbo.TABLE WHERE [id] = (?)";

$params = [1];

$query = sqlsrv_query($sqlc, $request, $params, array("Scrollable"=>"forward"));

$row = @sqlsrv_fetch_array($query, SQLSRV_FETCH_ASSOC);

$dtObject = $row['dt']; // 2019-08-31 23:59:00.000000, !timezone local!

// get id by same date

$request = "SELECT [id] FROM DB.dbo.TABLE WHERE [dt] = (?)";

$params = [$dtObject];

$query = sqlsrv_query($sqlc, $request, $params, array("Scrollable"=>"forward"));

$row = @sqlsrv_fetch_array($query, SQLSRV_FETCH_ASSOC);

$id = $row['id']; // PHP5:OK; PHP7:no result

// PHP7 workaround

$request = "SELECT [id] FROM DB.dbo.TABLE WHERE [dt] = CAST((?) as DATETIME)";

?>

所以,当我这样做的时候

GET date from datetime column

我收到当地时区的准确日期。

但当我在第二个请求中使用此日期时,它与存储的日期不匹配,直到

CAST to datetime

补充。

即使我把所有时区切换到

UTC

下一期没有圆形和附加的类型转换就无法击败:

// create datetime object

// lets imagine now is 2019-08-28 05:55:08.392200 UTC+00:00

$dtObject = date_create('now');

$request = "INSERT INTO DB.dbo.TABLE([id],[dt]) VALUES(?,?)";

$params = [2,$dtObject];

$query = sqlsrv_query($sqlc, $request, $params, array("Scrollable"=>"forward"));

// table now has row

// 2 2019-08-28 05:55:08.393 // NOTE: .393

// get id by same date

$request = "SELECT [id] FROM DB.dbo.TABLE WHERE [dt] = (?)";

$params = [$dtObject];

$query = sqlsrv_query($sqlc, $request, $params, array("Scrollable"=>"forward"));

$row = @sqlsrv_fetch_array($query, SQLSRV_FETCH_ASSOC);

$id = $row['id']; // PHP5:OK; PHP7:no result

// PHP7 workaround

$request = "SELECT [id] FROM DB.dbo.TABLE WHERE [dt] = CAST((?) as DATETIME)";

?>

问题

为什么,当阅读

(选择)

SQL日期时间

,我明白了

php日期时间

写作时使用正确的时区(本地)

(插入)

一切都很好,但是当谈到比较

WHERE [dt] = (PHP DateTime Object)

,日期不匹配?

编辑2

临时解决方案

由于项目中的所有数据库查询都是使用包装类执行的,因此我已将所有datetime参数配置为字符串的一处转换:

foreach ($this->request_params as $key => $value) {

if ( !$this->fulldatetime && $value instanceof DateTime )

# OLD datetime fields compat

$params[$key] = $value->format( "Y-m-d\TH:i:s." ).substr( $value->format( "u" ), 0, 3 );

else

$params[$key] = $value;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值