14

所以我有一个带有评论功能的网站,其中评论的时间戳存储在 MySQL 数据库中。据我了解,时间戳在存储时转换为 UTC,然后在检索时转换回默认时区。就我而言,我的服务器位于中央夏令时时区 (CDT)。

我计划通过输入表单从每个用户那里获取时区。我只是想知道如何将 TIMESTAMP 值转换为用户的时区。

  • 首先,我会从 UTC 转换为本地时区吗?还是 CDT 到本地时区?
  • 其次,我将如何在 PHP 中做到这一点?我会这样做:
$userTimezone = new DateTimeZone($userSubmittedTimezoneString);
$myDateTime = new DateTime($storedTimestamp, $userTimezone);

...或者这不正确?

4

4 回答 4

21

日期/时间/日期时间值在您提供时存储在 MySQL 中。即,如果您INSERT将字符串2012-04-17 12:03:23放入一DATETIME列,这就是将要存储的值。它将在内部转换为可能准确也可能不准确的时间戳(见下文),但是当您再次查询该值时,您将得到相同的值;往返是透明的。

如果您尝试在 SQL 中进行时间计算,可能会出现问题。即任何需要SQL 来考虑时区和/或服务器时间的操作。例如,使用NOW(). 对于任何这些操作,正确设置时区和/或服务器时间。请参阅时区问题

如果这与您无关并且您只需要在 PHP 中进行计算,您只需要确保您知道要从哪个时区转换到哪个时区。为此目的,将所有时间标准化为 UTC很方便,但这不是必需的,因为从任何时区到任何其他时区的时区转换也一样有效,只要您清楚要从哪个时区转换并。

date_default_timezone_set('Asia/Tokyo'); // your reference timezone here

$date = date('Y-m-d H:i:s');

/* INSERT $date INTO database */;

$date = /* SELECT date FROM database */;

$usersTimezone = new DateTimeZone('America/Vancouver');
$l10nDate = new DateTime($date);
$l10nDate->setTimeZone($usersTimezone);
echo $l10nDate->format('Y-m-d H:i:s');
于 2012-04-17T03:55:57.703 回答
1

没有可靠的方法来获取用户的时区。时区信息不在 HTTP 标头中发送。您能做的最好的事情是:

  1. 将 IP 地址与地理数据库匹配 - 或 -
  2. 使用 Javascript 获取用户计算机上设置的时间,然后将其发送到服务器 (AJAX) 或在客户端创建时间字符串。
于 2012-04-17T02:37:12.683 回答
0
$timezone = new DateTimeZone('America/Vancouver');

$date = new DateTime(date('m/d/Y h:i:s a', time()));
$date->setTimeZone($timezone);
echo $date->format('l F j Y g:i:s A')."\n";

替换new DateTime(date('m/d/Y h:i:s a', time()));new DateTime("UTC Time");

DateTimeZone()您可以为每个用户输入创建一个新对象。

于 2012-04-17T03:23:50.177 回答
0

做到这一点的方法是使用javascript。我认为最好的方法是将用户 GMT 存储到他的 cookie 中,然后在 PHP 进程表单中检索它。

<script language="javascript">

function TimeZoneCookie()
{
 var u_gmt = (-(new Date().getTimezoneOffset()))/60;
 var o_date = new Date("December 31, 2025");
 var v_cookie_date = o_date.toGMTString();
 var str_cookie = "utimezone="+u_gmt;
 str_cookie += ";expires=" + v_cookie_date;
 document.cookie=str_cookie;
}
//---------------------
TimeZoneCookie();

</script>

u_gmt解释:

  1. Date().getTimezoneOffset()以分钟为单位返回到 GMT-0的偏移量
  2. 由于getTimezoneOffset()会将偏移量返回到 GMT-0而不是从 GMT-0开始,因此我们需要将其转过来。如何?很简单,只要知道-*-=+& -*+=-。如果你知道基本的数学,你就已经知道这个原理了。
  3. 正如我在步骤 1 getTimezoneOffset()中所说的,将以分钟为单位返回偏移量,所以我们只需将其除以 60,就可以得到 gmt 偏移量格式。

结果: (-(new Date().getTimezoneOffset()))/60


现在在 PHP 中检索 cookie:

<?php

$user_timezone = $_COOKIE['utimezone'];

?>
于 2012-04-17T03:28:24.107 回答