MySQL 和 PHP UTC 时间在数字格式中不同

MySQL and PHP UTC time differs when in number format

我正在尝试创建一个登录系统,为了重设密码或确认帐户,我有一个带有 'expiration date' 的列,为了在任何地方都有效,我存储在UTC 时间。但是我遇到了一些非常奇怪的事情。当我从 SQL 获得 formatted UTC 时间和从 PHP 获得 formatted UTC 时间时,两者是相同的。但是当我输入 numbers(我不知道该格式的真实名称是什么)时,它们恰好相差 7200(与 2 小时相差相同)。如果有人知道为什么会这样?谢谢。

这是我用来调试的代码:

<?php

$con = mysqli_connect('localhost', 'root', '', 'clients');

updateUserUTCTime($con, 3);
$user = getUserAssocArray($con, 3);

echo $user['date_utc'];
echo '<br>';
echo gmdate("Y-m-d H:i:s", time());
echo '<br>';
echo '<br>';
echo strtotime($user['date_utc']);
echo '<br>';
echo gmdate(time());
echo '<br>';
echo '____________';
echo '<br>';
echo strtotime($user['date_utc']) - gmdate(time());

function updateUserUTCTime($con, $id=1){
    $query = '
    update datetests 
    set date_utc = UTC_TIME()
    where id = '.$id.'
    ;';

    return mysqli_query($con, $query);
}

function getUserAssocArray($con, $id=1){
    $query = 'select * from datetests where id = '.$id.';';
    $result = mysqli_query($con, $query);
    $result = mysqli_fetch_assoc($result);
    return $result;
}

输出(当时我有 运行 代码)是:

2021-09-23 09:54:06
2021-09-23 09:54:06

1632383646
1632390846
____________
-7200

请注意,格式化时它们相同,但不同时,它们相差 7200 个单位...

Ps: 在数据库中,我使用“DATETIME”类型来存储 UTC_TIME。 我正在使用以下函数获取每种语言的 UTC 时间:

gmdate(time()) -> PHP

UTC_TIME() -> MySQL

时区处理可能是 xss 脖子上的痛。

  • 1632383646 是 07:54:06 UTC,09:54:06 CET
  • 1632390846 是 09:54:06 UTC,11:54:06 CET

php 的 time() 总是 returns UTC 中的 UNIX timestamp 号码(如 1632390846)。 UNIX 时间戳始终采用 UTC。 (只要您的机器正确配置了本地时区。)

但是,php 的 strtotime() 函数接受一个 date/time 字符串 2021-09-23 09:54:06 就好像它是在本地时间并将其转换为 UNIX 时间戳。您的机器设置为 CET (+02:00),因此 strtime() 减去两个小时以获得时间戳,假定始终采用 UTC。

明智的应用程序设计,您可能明智地使用 MySQL 来完成所有时区处理。它已为该任务设置 remarkably well

  1. 始终使用 TIMESTAMP 数据类型。这样,您所有存储的 date/time 值都将采用 UTC。

  2. 如果你要走向全球,让每个用户选择她的时区偏好,使用 Europe/AmsterdamAsia/Kolkata 之类的字符串。 See this.

  3. 当您运行代表用户查询您的数据库时,首先给出这个MySQL语句

    SET time_zone = ###user-preference-string###
    

    并且您的所有查询结果都将以当地时间显示。

  4. 当你运行数据库维护查询时,先说

    SET time_zone = 'utc'
    

    并且您的输出将采用 UTC。