我正在创建一个论坛,它还存储了发送帖子的时间,我需要将其转换为用户的时区。
现在,MySQL数据库用UTC_TIMESTAMP()
存储时间(在DATETIME
类型的列中),我从http://www.ultramegatech.com/blog/2009/04/working-with-time-zones-in-php/上的代码创建了一个小函数,将时间转换为用户的时区。下面是函数:
function convertTZ($timestamp, $tz='UTC', $format='d-m-Y H:i:s') {
// timestamp to convert
$timestamp = strtotime($timestamp);
// the time formatting to use
$format = $format;
// the time zone provided
$tz = $tz;
// create the DateTimeZone object for later
$dtzone = new DateTimeZone($tz);
// first convert the timestamp into an RFC 2822 formatted date
$time = date('r', $timestamp);
// now create the DateTime object for this time
$dtime = new DateTime($time);
// convert this to the user's timezone using the DateTimeZone object
$dtime->setTimeZone($dtzone);
// print the time using your preferred format
$time = $dtime->format($format);
return $time;
}
我在http://assets.momo40k.ch/timezones.php做了一个测试页面。
现在,当我在数据库中插入一个帖子时,比如说,在我的时区11:50
(这是Europe/Rome
),它在UTC中插入09:50
,根据一些在线时区转换器,这是正确的。
但是当我尝试用convertTZ()
函数将其转换回Europe/Rome
时,它返回09:50
,就好像Europe/Rome
是UTC一样。如果我尝试将其转换为GMT+2:00时区,它将返回10:50
。有人知道这是为什么吗?
p.s.:我不使用CONVERT_TZ()
SQL
函数,因为我的服务器不支持命名时区,所以这个函数是我的解决方案。
确保您存储的时间戳是UTC:
$date = new DateTime($timestamp, new DateTimeZone("UTC"));
$date->format(DATE_W3C); // does it gives the expected result ?
顺便说一句,你的函数可以简化为:
function convertTZ($timestamp, $tz='UTC', $format='d-m-Y H:i:s') {
$dtime = new DateTime($timestamp, new DateTimeZone("UTC"))
$dtime->setTimezone(new DateTimeZone("UTC"));
return $dtime->format($format);
}
MySQL总是在内部以UTC格式存储TIMESTAMP字段(实际上,这是unix时间戳的定义)。因此,当你执行SELECT或UPDATE/INSERT/REPLACE操作时,你得到或设置的时间总是在MySQL服务器的本地时区。
所以一个常见的错误是存储UTC_TIMESTAMP(), MySQL将其解释为本地时间,因此当它将当前时间作为unix TIMESTAMP内部存储在字段中时,将其双重转换为UTC。