在PHP / MySQL应用程序中管理时区的最有效方法是什么?

时间:2011-07-04 05:28:23

标签: php mysql

我正在开发一个涉及使用时间戳的Web应用程序。我希望时间戳以尽可能少的配置显示在用户的时区中。从不同时区登录时,Facebook和Google日历都会自动更新其显示时间。

您用于处理网络应用中时区的最有效方法是什么?如果可能的话,我不想要求用户提供额外的输入。

这是我到目前为止的想法:

  1. 以UTC格式将所有时间戳存储在数据库中
  2. 保留一个数据库表,将时区与UTC偏移相关联,以及是否在该时区内观察到夏令时
  3. 根据客户端信息(IP地址?),找到用户的当前时区。此信息可以缓存在会话变量中,以防止重复读取表。
  4. 每当要显示数据库的时间戳时,请使用UTC偏移量
  5. 进行转换

    我发现很难相信那里已经没有什么可以做到的了。如果您有任何建议,我会很感激。

4 个答案:

答案 0 :(得分:1)

我建议另一个解决方案:

  1. 将所有日期存储在mysql timestamp列类型
  2. 在连接到mysql之后 - 用SET time_zone='<tz>'指定当前用户的时区,其中<tz>可以是+01:00偏移量或时区名称Asia/Vladivostok(对于后面的特殊时区db应该由DBA导入)
  3. 使用timestamp的好处是自动根据您在当前连接中指定的time_zone将日期转换为UTC和从UTC转换日期。

    有关时间戳的更多详细信息:http://dev.mysql.com/doc/refman/5.1/en/timestamp.html

    关于检索当前用户的时区(尽管这里有很多关于此主题的答案,让我们再次这样做):

    1. 只要Cookie中有TZ值(请参阅第4步) - 使用它。
    2. 对于注册/验证用户 - 您可以要求指定其时区并将其永久存储在数据库中。
    3. 对于来宾,您可以从javascript(Date.getTimezoneOffset())检索时区并使用ajax发送
    4. 如果是第一个请求/没有从ajax传递 - 通过IP猜测它
    5. 对于每个步骤(1-3) - 将时区保存到cookie。

答案 1 :(得分:0)

我认为你拥有的是一个很好的解决方案。

唯一的变化是获取用户的时区。您需要做的就是用一些javascript报告用户的时间。然后你知道偏移量。即使IP地址相同但用户更新计算机的时区也是有效的,因为它由于某种原因是不正确的。

答案 2 :(得分:0)

好的,我已经考虑了一些,使用了其他人发布的信息,这就是我认为最好的方法:

  1. 加载页面时,使用Javascript获取UTC时区偏移量:

    new Date().getTimezoneOffset();

  2. 通过AJAX将此值发回PHP脚本。 PHP脚本将数据格式化为+hh:mm-hh:mm格式,然后将此值存储在当前会话中。

  3. 对于所有后续数据库空缺,请运行查询SET time_zone="$Timezone",其中$Timezone是会话中缓存的值。

  4. 对包含时间数据的所有列使用MySQL TIMESTAMP类型。

  5. 我喜欢这种方法,因为它允许MySQL完成所有脏工作,并且不需要我必须管理的庞大时区数据库。

    你有什么想法?

答案 3 :(得分:0)

如果您想使用PHP解决此问题,请查看此信息 以下代码可用于查找当地时间和格林威治标准时间(GMT)。

<?php  
echo date("M d Y H:i:s", mktime(0, 0, 0, 1, 1, 1998));    # Local Time 
echo gmdate("M d Y H:i:s", mktime(0, 0, 0, 1, 1, 1998));  # GMT Time 
?>

使用以下步骤根据位置显示时间。

  1. 添加一个Session变量,用于存储本地和GMT时间的差异。
  2. 在显示在网站之前将差异添加到GMT时间。
  3. 例如,

    # Here shows the difference 
    $diff = (strtotime(gmdate("M d Y H:i:s",time())) - strtotime(date("M d Y H:i:s",time())));  
    
    echo '<br />'.(date("M d Y H:i:s",time()));          #  Oct 16 2013 08:09:23
    echo '<br />'.gmdate("M d Y H:i:s",(time()-$diff));  #  Oct 16 2013 08:09:23