PHP和MySQL存在时区问题
我的服务器时间以GMT为单位,每当有人在线时,我都会执行以下操作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
// 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
以避免MySQL中出现任何问题,在PHP中,我有time\u zone=UTC
date\u default\u timezone\u set('UTC')
- 使用
而不是UTC\u TIMESTAMP()
-一个是UTC,一个使用本地(会话)时区。如果您遵循上述第一点,请使用UTC_TIMESTAMP()NOW()
- 选择向用户显示时,在显示任何内容之前,
本地时区设置时区='
'
- 如果您必须显示内容,然后进行更新,请确保在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格式,并且只在需要显示时将其转换为正确的时区?感谢您的说明和示例:)