简体   繁体   English

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

[英]What is the most effective way to manage time zones in a PHP/MySQL application?

I'm developing a web application that involves the use of timestamps.我正在开发一个涉及使用时间戳的 web 应用程序。 I would like the timestamps to display in the user's time zone with as little configuration as possible.我希望时间戳以尽可能少的配置显示在用户的时区中。 Facebook and Google Calendar both update their displayed time automatically when logged into from different time zones.从不同时区登录时,Facebook 和 Google 日历都会自动更新其显示时间。

What is the most effective method you've used to deal with time zones in your web apps?您在 web 应用程序中处理时区的最有效方法是什么? If at all possible, I would like to require no additional input from the user.如果可能的话,我希望用户不需要额外的输入。

Here's what I'm thinking so far:到目前为止,这是我的想法:

  1. Store all timestamps in the database in UTC以UTC格式存储数据库中的所有时间戳
  2. Keep a database table that correlates time zones to UTC offsets, and whether daylight savings time is observed in that time zone保留将时区与 UTC 偏移相关联的数据库表,以及在该时区是否遵守夏令时
  3. Given client information (IP address?), find the user's current time zone.给定客户端信息(IP 地址?),找到用户当前的时区。 This information can be cached in a session variable to prevent repeated reads to the table.此信息可以缓存在 session 变量中,以防止重复读取表。
  4. Whenever a timestamp from the database is to be displayed, convert it using the UTC offset每当要显示数据库中的时间戳时,使用 UTC 偏移量对其进行转换

I find it hard to believe that there's nothing out there already that does this.我发现很难相信没有任何东西可以做到这一点。 If you have any suggestions, I'd appreciate it.如果您有任何建议,我将不胜感激。

I'd propose another solution:我会提出另一个解决方案:

  1. Store all the dates in mysql timestamp column type将所有日期存储在 mysql timestamp列类型中
  2. Right after connect to mysql - specify current user's timezone with SET time_zone='<tz>' where <tz> can be either +01:00 offset or timezone name Asia/Vladivostok (for the latter special timezones db should be imported by DBA)在连接到 mysql 之后 - 使用SET time_zone='<tz>'指定当前用户的时区,其中<tz>可以是+01:00偏移量或时区名称Asia/Vladivostok (对于后者的特殊时区,db 应由 DBA 导入)

The benefit of using timestamp is that it automatically converts the date to and from UTC, according to the time_zone you've specified in the current connection.使用timestamp的好处是它会根据您在当前连接中指定的time_zone自动将日期与 UTC 转换。

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

About retrieving current user's timezone (even though there are a lot of answers here on SO about this topic, let's do that once again):关于检索当前用户的时区(尽管这里有很多关于这个主题的答案,让我们再做一次):

  1. As long as there is a TZ value in cookies (look at step 4) - use it.只要 cookies 中有一个 TZ 值(请看第 4 步) - 使用它。
  2. For registered/authenticated users - you can ask to specify their timezone and store it permanently in DB.对于已注册/经过身份验证的用户 - 您可以要求指定他们的时区并将其永久存储在数据库中。
  3. For guests you can retrieve the timezone from javascript ( Date.getTimezoneOffset() ) and send it with ajax对于客人,您可以从 javascript ( Date.getTimezoneOffset() ) 中检索时区并将其与 ajax 一起发送
  4. If it is the first request/nothing passed from ajax - guess it by IP如果它是第一个请求/没有从 ajax 传递 - 由 IP 猜测
  5. For each step (1-3) - save timezone to a cookie.对于每个步骤 (1-3) - 将时区保存到 cookie。

If you like to solve this issue using PHP, check this out.如果您想使用 PHP 解决此问题,请查看此内容。
The following code can be used to find the local time and the Greenwich Mean Time(GMT).以下代码可用于查找本地时间和格林威治标准时间 (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 
?>

Use these steps to show the time based on location.使用这些步骤根据位置显示时间。

  1. Add a Session variable which stores the difference of local and GMT time.添加一个 Session 变量,用于存储本地时间和 GMT 时间的差异。
  2. Add the difference to the GMT time before showing in the site.在网站中显示之前将差异添加到 GMT 时间。

For example,例如,

# 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

I think what you have is a great solution.我认为你所拥有的是一个很好的解决方案。

The only alteration is in getting the user's timezone.唯一的改变是获取用户的时区。 All you need to do is have bit of javascript report the user's time.您需要做的就是有一点 javascript 报告用户的时间。 Then you know the offset.然后你知道偏移量。 That works even if the IP address is the same but the user updates the computer's timezone because it was incorrect for some reason.即使 IP 地址相同但用户更新计算机的时区,因为它由于某种原因不正确,这也有效。

Ok, I've thought about it some more, used the info posted by some other people, and here's what I think the best approach is:好的,我考虑了更多,使用了其他人发布的信息,这就是我认为最好的方法:

  1. When a page is loaded, use Javascript to get the UTC timezone offset:加载页面时,使用 Javascript 获取 UTC 时区偏移量:

    new Date().getTimezoneOffset();

  2. Send this value back via AJAX to a PHP script.通过 AJAX 将此值发送回 PHP 脚本。 The PHP script formats the data into the form +hh:mm or -hh:mm , and then stores this value in the current session. PHP 脚本将数据格式化为+hh:mm-hh:mm形式,然后将该值存储在当前 session 中。

  3. For all subsequent database openings, run the query SET time_zone="$Timezone" , where $Timezone is the value cached in the session.对于所有后续数据库打开,运行查询SET time_zone="$Timezone" ,其中$Timezone是缓存在 session 中的值。

  4. Use the MySQL TIMESTAMP type for all columns containing time data.对包含时间数据的所有列使用 MySQL TIMESTAMP类型。

I like this approach because it lets MySQL do all the dirty work, and requires no huge time zone database that I have to manage.我喜欢这种方法,因为它让 MySQL 完成所有繁琐的工作,并且不需要我必须管理的庞大时区数据库。

What are your thoughts?你觉得呢?你有没有什么想法?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM