我有一个支持时区的 PHP-MySQL API。我的数据库采用 UTC 格式,所有日期时间计算均采用 UTC 时间,只是在向用户显示数据时转换为本地时间。
问题在于尝试为不同时区的用户检索自然时间间隔内的数据,例如周、月、年等。 DB 列的类型为 DateTime
并以 UTC 格式存储日期。如果我需要按月分组的所有行并且只使用存储在数据库中的 UTC 日期,我会得到一些错误的行,如果时区差异使一些行改变了它的月份。
示例:值为 2015-05-01 00:00:00
的行在 UTC 中是 5 月,但对于负时间的任何用户来说都应该是 4 月区域。
所以使用 UTC 不是这里的解决方案。我首先需要将这些日期转换为客户端时区。
我可以使用哪种方法来克服这个问题?
例如,这是按周对一些数据进行分组的 View :
SELECT `individuals_id`,
Str_to_date(Concat(Yearweek(`sessions_date`, 5), ' Monday'), '%X%V %W') AS `sessions_date`,
`protocol_index`,
`zone_index`,
Avg(`asymmetry_dom`) AS `asymmetry_dom`,
Avg(`asymmetry_rl`) AS `asymmetry_rl`,
FROM `sessions_data_view`
GROUP BY `individuals_id`,
Yearweek(`sessions_date`, 5),
`protocol_index`,
`zone_index`
ORDER BY `individuals_id`,
Yearweek(`sessions_date`, 5),
`protocol_index`,
`zone_index`
问题是 Yearweek()
应该根据用户时区为一行提供不同的输出。如果想为用户提供一致的结果,则不可能使用 UTC 中的 sessions_date 列。
现在我不知道用户时区,但这不应该是一个限制,因为该应用程序处于设计阶段,任何内容都可以更改。
API 是一个获取 HTTP 请求的 PHP 应用程序。它与一个 PHP 数据库类对话,该类将所有查询包装到 MariaDB 数据库。来自 API 的所有响应都以 JSON 格式给出,日期格式为 UTC 字符串。数据通过网络应用程序显示。 DateTime Javascript 对象负责将来自 API 的响应转换为客户端时区的正确日期。
最佳答案
首先,假设他们的计算机时间设置正确,获取客户时区的唯一可靠方法是通过 javascript。
解决方案一 - Javascript 到 PHP
我建议使用以下 javascript 收集用户时区:
var timeZone = new Date().getTimezoneOffset();
您需要将此值存储在数据库中。然后,您使用类似于以下的 PHP 代码格式化 UTC 时间:
$date = new DateTime();
$timezone = new DateTimeZone('Australia/Sydney');
$date->setTimezone($timezone);
$formatted_date = $date->format('Y-m-d H:i:s');
解决方案二 - PHP 到 Javascript
使用以下代码将 UTC 字符串转换为 unix 时间戳:
$time = strtotime($utc);
然后您将其返回给浏览器,并使用 javascript 将其格式化为如下所示:
var date = new Date(timestamp * 1000),
datevalues = [
date.getFullYear(),
date.getMonth()+1,
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
];
祝你好运!
编辑:要转换 MySQL 以用于查询,请使用 CONVERT_TZ
,格式为:
CONVERT_TZ('日期/时间字段','起始时区','结束时区')
例如:
select *, DATE_FORMAT(CONVERT_TZ(str_to_date(timestamp),'UTC','US/Eastern'), '%m/%d/%y %h:%i %p') as 'Date - Eastern' FROM table`
关于mysql - 在 MySQL 中检索客户端时区的自然时间间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30001820/