PHP和MySQL存在时区问题

Mic*_*ICE 2 php mysql timezone

我的服务器时间是格林尼治标准时间,每当有人上线时我会做以下事情.

// 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."'");
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是这样的...每当有人做某事时,它会在用户当地时间存储日期/时间......导致我一大堆问题.

我想要的只是将所有内容存储在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);
}
Run Code Online (Sandbox Code Playgroud)

这是我将日期戳变成秒的功能......

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]);
}
Run Code Online (Sandbox Code Playgroud)

最后,我如何比较日期:

    $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>";
    }
Run Code Online (Sandbox Code Playgroud)

raz*_*zed 9

这里的诀窍是知道列类型date_last_active是什么.我已经有足够的经验TIMESTAMPDATETIME知道一个翻译(和荣誉)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)
Run Code Online (Sandbox Code Playgroud)

所以,这是我做的:

  • 插入数据库时​​,在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中适当的时区更改来支持您的呼叫.

希望这足以弄清楚如何处理这个问题.如果您有其他问题,请与我们联系.