当前位置: 首页 > 面试题库 >

PHP和MySQL存在时区问题

郎项禹
2023-03-14
问题内容

我的服务器时间是格林尼治标准时间(GMT),每当有人在线时,我都会执行以下操作。

// Set a default timezone
$defaultTimeZone = 'America/Toronto';

// load the user, if they are online...
$onlineUser = new user();
if (isset($_SESSION['user_id']))
{
    if ($onlineUser->loadUser($_SESSION['user_id']))
    {
        $defaultTimeZone = $onlineUser->timeZone;
    }
}

// set time zones
date_default_timezone_set($defaultTimeZone);
$db->query("SET SESSION time_zone = '".$defaultTimeZone."'");

所以,我的问题是……每当有人执行某项操作时,它都会将日期/时间存储在用户本地时间中……这给我带来了很多麻烦。

我想要的是将所有内容存储在GMT中,但要让用户在其本地时区查看数据并与之交互。

编辑:

这是我更新用户状态的方法:

public function updateStatus()
{
    global $db, $common, $config;

    // update the user record
    $data = array(
        'date_last_active'  => new Zend_Db_Expr('NOW()')
    );

    $db->update('users', $data, 'user_id='.$this->userId);
}

这是我将日期戳转换为秒的功能。

public function dateTimeToUnixTime($dateString)
{
    if (strlen($dateString) < 10)
    {
        return "";
    }

    $parseDateTime = split(" ", $dateString);
    $parseDate = split("-", $parseDateTime[0]);

    if (isset($parseDateTime[1]))
    {
        $parseTime = split(":", $parseDateTime[1]);
    }
    else
    {
        $parseTime = split(":", "00:00:00");
    }

    return mktime($parseTime[0], $parseTime[1], $parseTime[2], $parseDate[1], $parseDate[2], $parseDate[0]);
}

最后,我如何比较日期:

    $date = $oUser->dateLastActive;

    $lastSeen = abs($common->dateTimeToUnixTime(date('Y-m-d H:i:s')) - $common->dateTimeToUnixTime($date));

    if ($lastSeen < 300 )
    {
        echo "<font size='1' color='green'><strong>Online</strong></font>";
    }

    if ($lastSeen >= 300)
    {
        echo "<font size='1' color='black'><strong>Offline</strong></font>";
    }

问题答案:

这里的技巧是知道什么是列类型date_last_active。我有足够的经验,TIMESTAMP并且DATETIME知道一个翻译(并尊重)MySQL
time_zone会话变量,而另一个没有。

mysql> SET SESSION time_zone = 'America/New_York';
Query OK, 0 rows affected (0.00 sec)

mysql> create table timetest ( dt datetime NULL, ts timestamp NOT NULL DEFAULT 0 );
Query OK, 0 rows affected (0.06 sec)

mysql> INSERT INTO timetest ( dt, ts ) VALUES ( UTC_TIMESTAMP(), UTC_TIMESTAMP() );
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO timetest ( dt, ts ) VALUES ( NOW(), NOW() );
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM timetest;
+---------------------+---------------------+
| dt                  | ts                  |
+---------------------+---------------------+
| 2009-06-27 17:53:51 | 2009-06-27 17:53:51 | 
| 2009-06-27 13:53:54 | 2009-06-27 13:53:54 | 
+---------------------+---------------------+
2 rows in set (0.00 sec)

mysql> set session time_zone='UTC';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM timetest;
+---------------------+---------------------+
| dt                  | ts                  |
+---------------------+---------------------+
| 2009-06-27 17:53:51 | 2009-06-27 21:53:51 | 
| 2009-06-27 13:53:54 | 2009-06-27 17:53:54 | 
+---------------------+---------------------+
2 rows in set (0.00 sec)

所以,这是我的工作:

  • 插入数据库时​​,请在PHP和MySQL中使用UTC。在my.cnf我有:time_zone=UTC避免任何问题,MySQL和PHP中的我date_default_timezone_set('UTC')
  • 使用UTC_TIMESTAMP()而不是NOW()-一种是UTC,一种是使用本地(会话)时区。如果您遵循上面的第一点,请使用UTC_TIMESTAMP()。
  • 选择显示给用户时,在显示任何内容之前先设置set time_zone=' local_time_zone'
  • 如果必须显示内容,然后进行更新,请确保将您的呼叫括在PHP和MySQL中的相应时区更改中。

希望这足以弄清楚如何解决此问题。如果您还有其他问题,请告诉我。



 类似资料:
  • 问题内容: 我正在尝试将时区系统集成到我的应用程序中,直到现在为止,我一直在努力避免制作时区感知的应用程序- 但是它是一项强制性要求,因此别无选择。TimeZones只是在我头上。我已经在PHP.net和其他站点(包括但不限于SO)上阅读了多个主题。但是我永远也无法掌握。 因此,我想知道是否有人可以在这里帮助我:(我想要做的是在我的应用程序中使用偏好选项,以允许用户从选择菜单中选择自己的时区,但是

  • 问题内容: 我正在制作一个需要使用PHP 函数将日期存储在MySQL中的应用程序。 这些日期需要在MySQL中使用函数返回以小时为单位的时差进行比较,例如: 但是问题是– PHP date函数使用PHP时区设置,而该函数从MySQL服务器获取MySQL timezome。 我正在尝试解决此问题: 它仅适用于PHP。 它仅适用于PHP。 此返回为空。 这从MySQL的控制台抛出错误。 而且对于MyS

  • 问题内容: 我有一个对象,我需要将其以格式插入MySQL的datetime字段中。 这给了我准备好的SQL语句字符串: 无论我指定的时区如何,返回的时间戳都是相同的时间戳。它忽略了我指定的带有时区的Calendar对象。怎么回事,我在做什么错? 问题答案: 时区只是查看日期(这是固定时间点)的不同方式。我在这里写了一个小例子(请注意断言): 此代码段的输出是(结果将根据执行日期/时间而有所不同):

  • 它给出了准备好的SQL语句字符串: 无论我指定的时区如何,返回的时间戳都是相同的时间戳。它忽略了我指定的带有时区的Calendar对象。这是怎么回事,我做错了什么?

  • 我在使用PHP strtotime函数是,遇到了+9时区的问题。 得到的结果是 2024-01-01 09:00:00 请问到底该怎么解决才能使 strtotime 直接得到0点的时间戳? 我检查了系统的时区,timedatectl 返回的结果 PHP date_default_timezone_get() 返回的是PRC。 即便使用 DateTime 得到的依然是2024-01-01 09:00

  • 问题内容: 这个问题是一个相当开放的问题。我已经将MS SQLServer的存储过程与经典的ASP和ASP.net一起使用了一段时间,并且非常喜欢它们。 我正在从事一个小型的业余项目,由于各种原因,LAMP路线已经消失。在MySQL和PHP5中使用存储过程有任何提示/技巧/陷阱或良好的起点吗?我的MySQL版本支持存储过程。 问题答案: 算了,它比PDO难用得多,应该已经删除了。的确,它引入了对m