Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP和MySQL存在时区问题_Php_Mysql_Timezone - Fatal编程技术网

PHP和MySQL存在时区问题

PHP和MySQL存在时区问题,php,mysql,timezone,Php,Mysql,Timezone,我的服务器时间以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

我的服务器时间以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]);
}
公共函数dateTimeToUnixTime($dateString)
{
if(strlen($dateString)<10)
{
返回“”;
}
$parseDateTime=split(“,$dateString);
$parseDate=split(“-”,$parseDateTime[0]);
if(isset($parseDateTime[1]))
{
$parseTime=split(“:”,$parseDateTime[1]);
}
其他的
{
$parseTime=split(“:”,“00:00:00”);
}
返回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=$oUser->dateLastActive;
$lastSeen=abs($common->dateTimeToUnixTime(date('Y-m-dh:i:s'))-$common->dateTimeToUnixTime($date));
如果($lastSeen<300)
{
echo“在线”;
}
如果($lastSeen>=300)
{
echo“离线”;
}

这里的诀窍是知道上次激活的列类型是什么。我对
TIMESTAMP
DATETIME
有足够的经验,知道其中一个翻译(并尊重)MySQL时区会话变量,而另一个不翻译

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\u zone=UTC
    以避免MySQL中出现任何问题,在PHP中,我有
    date\u default\u timezone\u set('UTC')
  • 使用
    UTC\u TIMESTAMP()
    而不是
    NOW()
    -一个是UTC,一个使用本地(会话)时区。如果您遵循上述第一点,请使用UTC_TIMESTAMP()
  • 选择向用户显示时,在显示任何内容之前,
    设置时区='
    本地时区
    '
  • 如果您必须显示内容,然后进行更新,请确保在PHP和MySQL中使用适当的时区更改来括起您的调用

希望这足以说明如何解决这个问题。如果您还有其他问题,请告诉我。

我认为Mysql的NOW()函数存储当前时区,这肯定很麻烦,我会检查CONVERT_TZ(dt,from_TZ,to_TZ),这可以解决您的问题,而且我相信php的time()返回服务器时间,您可以存储它。唯一的缺点是必须将返回值转换为与datetime/timestamp兼容的值,或者将其存储为varchar。使用convert_tz的缺点是,最终可能会出现一些难看的查询,并且每次使用它时都必须计算出当前时区。

我花了将近半天的时间来解决这个问题,我想我需要帮助其他人。所以我给你们提供了一些避免时区问题的指南

mysql>SET SESSION time_zone='offset'; 
mysql>SELECT NOW();
首先,您有两个选择,一个是使用MYSQL时区,另一个是PHP 时区如果你想远离时区的噩梦,就不要把它们混在一起

如果选择MYSQL时区:

插入:

fieldname: yourfieldname

datatype: timestamp 

default: CURRENT_TIMESTAMP
更新:

UPDATE YOUR_TABLE SET youfieldname = NOW() WHERE CONDITION;
$sql = "UPDATE YOUR_TABLE SET yourdatetimefield = '".date('Y-m-d H:i:s')."'";
供选择:

$sql = "SELECT yourdatetimefield FROM yourtable";
您只需要为应用程序设置require时区,并自动将存储的时间戳转换为指定的时区

mysql>SET SESSION time_zone='offset'; 
mysql>SELECT NOW();
偏移量示例:+05:30对于印度,用同样的方法查找您所在地区的偏移量

现在,您将从mysql获得所需的日期和时间

如果选择PHP时区

只需使用此功能设置您想要的时区:

date_default_timezone_set('America/Los_Angeles');
插入:

fieldname: yourfieldname

datatype: timestamp 

default: CURRENT_TIMESTAMP
字段名:您的字段名

数据类型:datetime

使用PHP日期函数存储日期和时间:

$sql = "INSERT INTO timetest ( YOURDATETIMEFIELD ) VALUES ('".date('Y-m-d H:i:s')."')";
更新:

UPDATE YOUR_TABLE SET youfieldname = NOW() WHERE CONDITION;
$sql = "UPDATE YOUR_TABLE SET yourdatetimefield = '".date('Y-m-d H:i:s')."'";
供选择:

$sql = "SELECT yourdatetimefield FROM yourtable";

我希望这能对您有所帮助。

为什么不将所有内容都保留在数据库中的GMT格式,并且只在需要显示时将其转换为正确的时区?感谢您的说明和示例:)