首页 > 解决方案 > MySQL 和 PHP UTC 时间在数字格式时不同

问题描述

我正在尝试创建一个登录系统,为了重置密码或确认帐户,我有一个带有“到期日期”的列,并且为了使该到期在任何地方都能正常工作,我以 UTC 时间存储。但是我遇到了一些非常奇怪的事情。当我从 SQL获取格式化的 UTC 时间和从 PHP 获取格式化的UTC 时间时,两者都是相同的。但是当我得到数字时(我不知道该格式的真实名称是什么),它们正好相差 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

标签: phpmysqldatetimetimezoneutc

解决方案


时区处理可能会让 xss 感到头疼。

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

phptime()总是以 UTC 格式返回UNIX 时间戳编号(如 1632390846)。UNIX 时间戳始终采用 UTC。(只要您的机器正确配置了本地时区。)

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

在应用程序设计方面,使用 MySQL 进行所有时区处理可能是明智之举。它为这项任务设置得非常好

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

  2. 如果您要走向全球,请让每个用户选择她的时区偏好,使用类似Europe/Amsterdamor的字符串Asia/Kolkata看到这个

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

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

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

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

    SET time_zone = 'utc'
    

    并且您的输出将采用 UTC。


推荐阅读