提问人:Kyle Noland 提问时间:8/21/2008 最后编辑:NiteshKyle Noland 更新时间:2/5/2017 访问量:7886
处理不同时区的PHP服务器和MySQL服务器
Dealing with PHP server and MySQL server in different time zones
问:
对于我们这些使用标准共享主机包(例如GoDaddy或Network Solutions)的人来说,当您的托管服务器(PHP)和MySQL服务器处于不同的时区时,您如何处理日期时间转换?
另外,是否有人有一些最佳实践建议来确定您网站的访问者所在的时区并适当地操作日期时间变量?
答:
将所有内容存储为 UTC。您可以在客户端级别进行转换,也可以使用客户端设置在服务器端进行转换。
评论
从 PHP 5.1.0 开始,您可以使用 date_default_timezone_set() 函数来设置脚本中所有日期/时间函数使用的默认时区。
对于MySql(引自MySQL服务器时区支持页面)
在MySQL 4.1.3之前,服务器仅在启动时设置的系统时区运行。从 MySQL 4.1.3 开始,服务器维护多个时区设置,其中一些可以在运行时修改。
您感兴趣的是时区的每连接设置,您将在脚本开始时使用该设置
SET timezone = 'Europe/London';
至于检测客户端时区设置,您可以使用一些 JavaScript 来获取该信息并将其保存到 cookie 中,并在后续页面读取中使用它来计算正确的时区。
//Returns the offset (time difference) between Greenwich Mean Time (GMT)
//and local time of Date object, in minutes.
var offset = new Date().getTimezoneOffset();
document.cookie = 'timezoneOffset=' + escape(offset);
或者,您可以为用户提供自行设置时区的 chioce。
由于之前遇到过 dateTime 类型问题,我将所有日期保存为 bigint。我将 time() PHP 函数的结果保存到其中,现在它们算作在同一时区:)
回复 Željko Živković 的答案,像“欧洲/伦敦”这样的时区描述符只有在 mySQL 管理员将时区表添加到系统并保持更新时才有效。
否则,您只能使用数字偏移量,例如“-4:00”。幸运的是,php date('P') 格式提供了它(从 5.1.3 开始)
因此,在假设您可能拥有的应用程序配置文件中
define('TZ', 'US/Pacific');
....
if (defined('TZ') && function_exists('date_default_timezone_set')) {
date_default_timezone_set(TZ);
$mdb2->exec("SET SESSION time_zone = " . $mdb2->quote(date('P')));
}
这意味着PHP和mySQL将就使用哪个时区偏移量达成一致。
始终使用 TIMESTAMP 来存储时间值。该列实际上存储为 UNIX_TIME(纪元),但在写入时隐式从当前time_zone偏移量转换,在读取时从当前偏移量转换回来。
如果要显示其他时区用户的时间,请在上面设置他们的给定时区,而不是全局 define()。当您的应用程序看到结果集时,mySQL将自动转换TIMESTAMP值(这有时可能是一个问题,如果您也需要实际知道事件的原始时区,那么它需要在另一列中)
至于“为什么不将所有时间都存储为 int”,这确实会失去比较和验证日期的能力,并且意味着您始终必须在应用程序级别转换为日期表示(当您直接查看数据时,这很难看 - 快,1254369600发生了什么?
在 php 中,在 php.ini 文件中设置时区:ini_set("date.timezone", "America/Los_Angeles");
或者在特定的页面中,您可以做到:date_default_timezone_set("America/Los_Angeles");
在 mysql 中,您可以执行以下操作:SET GLOBAL time_zone = 'America/Los_Angeles';
评论