Using time zones in a PHP web application
我已经找了几个小时了,看看在php/mysql web应用程序中使用时区的最佳方法是什么,很难找到一个明确的答案。根据我迄今为止所学,最好将每个人的资料以UTC格式存储在数据库中(如果我错了,请纠正我)。
当一个用户注册时,我会向他们询问那里的时区,然后将其存储在那里。此格式为下拉菜单:
1 |
我正在构建的应用程序将允许用户在未来设置人员安排(会议),就像日历一样。很明显,在一年的时间里,不同的时区有不同的夏令时,你知道我该如何应付吗?
假设一个来自英国的用户在2013年1月24日下午3:00安排了一个会议,并邀请了一个住在加利福尼亚的人参加这个会议,我如何才能让美国人在他/她的时区看到这个会议,而英国用户在他/她的时区看到这个会议?(请注意,两个用户都已注册并设置了时区)。
有没有人对此有明确的解释,也许还有一些例子?或者可以指给我在哪里能找到它?
谢谢
我在一年多前为一个私人喷气机操作员编写的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连接设置的日期时间,除非用户在使用命令
php datetime类有一个名为timezone的属性,它是php datetimezone对象。DateTimeZone对象是使用精确时区的字符串指定的。时区列表是全面的,在世界各地有数百个单独的时区。PHP时区将自动计入夏令时。
当用户在Web应用程序中生成日期时间时,在用户配置文件的时区中构造一个php-datetime对象。然后使用
因此,用户生成一个datetime,并在用户指定的时区中生成一个php datetime对象:
1 2 3 4 5 6 7 8 | // set using an include file for user profile $user_timezone = new DateTimeZone('America/New_York'); // 1st arg in format accepted by PHP strtotime $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构造,然后转换为用户的时区。
1 2 3 4 | $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 datetime来存储datetime值,而不是timestamp数据类型。时间戳数据类型在这里的手册中介绍。
编辑:可以使用listIdentifiers生成一个数组,其中包含每个php时区字符串,这是datetimezone类的静态方法。
在MySQL中,您需要做的是:
这将导致时区适当地转换为每个人的本地时间。
编辑:
这是因为
所以,这意味着您可以将会话时区设置设置为特定用户的时区,然后在该用户的时区中返回所有时间。此外,您的
注意:在具有持久性MySQL连接的Web应用程序中,新用户请求的工作将继承连接的时区设置。别忘了为新用户重置它。
如果您正在运行一个为多个用户返回本地时间数据的查询,而这些用户恰好位于不同的时区,则不能利用此MySQL每会话功能集。您可以通过为不同的用户运行不同的查询并更改他们之间的时区设置来解决这个问题。
或者,您可以使用mysql函数
1 | CONVERT_TZ(datetime,'UTC','user_time_zone') |
或在每件物品上相似。
另外,Java和dotnet有自己的高质量时区操作系统。因此,您可以选择使用UTC时区设置运行MySQL服务器,并在应用程序中进行所有时区转换。