在PHP中使用时区MySQL


Working with timezone in PHP & MySQL

我应该如何处理时区。仅仅为用户存储偏移量安全吗?还是我也应该有区域/位置?当我比较Wikipedia和PHP中的偏移值时,有些不匹配。我应该相信哪一个?

最后,我应该如何在PHP中使用它。我可以做一个"时间-服务器偏移+用户偏移"吗?

如果你想保留所有的数据,区域和位置是很重要的。(在我看来)存储日期的最佳方式是存储UTC时间戳+位置。

对于某些计算来说,仅仅是偏移量可能就足够了,但如果你有一个时间戳,并且想知道像"+1天"这样的东西的确切时间,那么它可能是不够的。因为这在不同的国家有不同的夏令时规则。

因此,如果你想绝对确定你不会"丢失信息",并且将来无法进行基于时间的计算,请存储UTC时间戳和olson id(例如:Europe/Amsterdam)。

回答你的第二个问题,如果你有这两条信息,你可以很容易地用DateTime重建它:

$dt = new DateTime('@' . $timeStamp);
// Now convert it to the users timezone
$dt->setTimeZone(new DateTimeZone('Europe/Berlin'));
// Now you have a 'DateTime' object which you can easily display with the ->format function.

添加

我个人更喜欢将时间戳存储为整数。TIMESTAMP类型进行自动转换,我觉得最好让PHP应用程序处理这个问题,这对于我认为您的用例(用户的简单本地化)特别有意义。

使用DATETIME也可以,但是存储需求比仅仅使用整数要高得多。如果你更喜欢DATETIME,试着在你的应用程序中设置一个规则,总是将每个值存储为UTC,因为这样就不会有任何混乱,特别是在DST转换和本地时区的法律更改方面。

如果你只是想显示你的web应用程序的时间计算基于用户的本地时区,偏移量是无用的。对于大多数国家来说,抵消量每年变化两次,几乎每年都会有一两个国家发生变化。

如果你使用PHP的DateTime和DateTimeZone对象,你只需要位置。

最后一点建议:

在PHP应用程序中,人们倾向于混淆日期和时间,并以许多不同的格式(字符串,整数等)发送这些值,并混合GMT和UTC。试着为你自己制定一个规则,只在函数参数和返回值中发送DateTime对象,这样你就可以键入提示,并且变量的格式永远不会有任何疑问。这是值得的。

您可以使用填充时区的下拉菜单将数据库中的时区保存为字符串

当用户登录时,将时区保存在$_SESSION['timezone']变量中,并在脚本中设置时区,如下所示:

date_default_timezone_set($_SESSION['timezone']);

您提到了一个用户。我建议您让用户选择他/她的时区,并将其存储在您的数据库中。

下面是如何同步PHP(>=5.3)和MySQL每个会话和用户设置的时区。当你需要设置和同步时区时,把它放在它运行的地方。

date_default_timezone_set($my_timezone);
$n = new 'DateTime();
$h = $n->getOffset()/3600;
$i = 60*($h-floor($h));
$offset = sprintf('%+d:%02d', $h, $i);
$this->db->query("SET time_zone='$offset'");

其中$my_timezone是PHP时区列表中的一个:http://www.php.net/manual/en/timezones.php

PHP时区必须转换为MySQL的小时和分钟偏移量。这就是第1-4行。查询行使用Code Igniter框架,您可能不会使用它,但是查询显示在括号中。

如果你正在处理MySQL,你可以使用来自(mysql_tzinfo_to_sql)的时区信息,它将根据时区自动识别用户时间。并且必须创建一个类型为时间戳的列,用于存储用户的时区信息。