我曾在一年多之前为一家私人飞机运营商编写的PHP/MySQL应用程序中广泛处理了这种情况。这两个平台处理时区有不同的策略,但我将解释我是如何做到的。我将MySQL服务器设置为UTC,并在用户在注册过程中为用户配置文件指定的时区中运行每个PHP脚本。
MySQL和PHP(PHP 5.2及以上版本)都具有本机日期时间数据类型。MySQL的datetime是一个原始数据类型,而PHP 5.2及以上版本提供了内置的DateTime类。MySQL datetime数据类型不包括时区的元数据,但是PHP DateTime对象始终包括时区。如果PHP datetime构造函数没有在第二个参数中指定可选的时区,则PHP datetime构造函数使用php环境变量。
MySQL和PHP都在配置文件中设置默认时区。MySQL使用配置文件中设置的日期时间作为每个db连接的默认时区,除非用户在使用命令SET time_zone = [timezone];
开始连接后指定其他时区。PHP还使用服务器配置文件中设置的时区设置一个时区环境变量,可以在脚本开始后使用PHP函数date_default_timezone_set()
覆盖此环境变量。
PHP DateTime类具有一个名为timezone的属性,该属性是PHP DateTimeZone对象。DateTimeZone对象使用精确时区的字符串指定。 时区列表非常全面,涵盖世界各地数百个单独的时区。 PHP时区将自动考虑夏令时。
当用户在Web应用程序中生成日期时间时,在用户配置文件的时区中构造一个PHP datetime对象。然后使用setTimezone
方法将DateTime对象修改为UTC时区。现在您可以将用户的datetime存储为UTC值,并使用DateTimeformat
方法将数据表示为MySQL接受的格式字符串。
因此,用户生成日期时间,您在用户指定的时区中创建了一个PHP datetime对象:
$user_timezone = new DateTimeZone('America/New_York');
$date_object1 = new DateTime('8/9/2012 5:19 PM', $user_timezone);
$date_object1->setTimezone(new DateTimeZone('UTC'));
$formated_string = $date_object1->format('Y-m-d H:i:s');
$query_string = "INSERT INTO `t_table1` (`datetime1`) VALUES('$formated_string')";
从数据库中检索值时,请使用UTC时间构造,然后将其转换为用户所在的时区。
$query_string = "SELECT `datetime1` FROM `t_table1`";
$date_object1 = new DateTime($datetime_string_from_mysql, new DateTimeZone('UTC'));
$date_object1->setTimezone($user_timezone);
$string_for_display_in_application = $date_object1->format('m/d/Y g:i a');
使用此方法,您的日期时间值始终在数据库中以UTC格式存储,用户始终以其个人资料时区的形式查看这些值。如果需要,PHP会为每个时区进行夏令时校正。
一个需要注意的问题:这个解释并不包括MySQL时间戳数据类型。我建议使用MySQL datetime数据类型来存储日期时间值,而不是时间戳数据类型。关于时间戳数据类型,请参阅手册
这里。
编辑:您可以使用DateTimeZone类的静态方法
listIdentifiers生成包含每个PHP时区字符串的数组。