2

你好 stackoverflow 社区。

我开发了一个网络应用程序,其概念是根据过去的时间序列显示历史货币汇率。

例如,用户可以请求从 2020 年 5 月 22 日 13:00 到 2020 年 5 月 26 日 22:00 的汇率。然后我的后端运行一个循环并每小时获取这两个日期时间之间的费率。

数据库中的所有费率都存储在 GMT 时区。

这就是问题所在。假设用户从时区偏移 +10:00 发出请求。因此,如果此用户选择最后日期时间 2020 年 5 月 26 日 22:00,我想我应该从我的数据库中获取 2020 年 5 月 26 日 12:00 的费率,因此减去 10 小时。

可能这听起来很愚蠢,但我坚持这一点。

我的逻辑是什么:

a) 通过前端的 javascript 获取用户时区偏移量

var get_timezone_offset = new Date().getTimezoneOffset();

var hrs = parseInt(-(timezone_offset / 60));

var mins = Math.abs(timezone_offset % 60);

var timezone_offset = hrs + ':' + mins;

b) 将用户时区偏移量发送到我的后端

c) 从我的数据库中获取汇率,并通过 PHP 的 Datetime 对象将存储的日期从 GMT 转换为用户时区偏移量

$date = new \DateTime('2020-05-26 22:00');

$date->modify(-10 hours);

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

这是正确的吗?我不会向我的用户显示错误的费率。

先感谢您

4

1 回答 1

2

请阅读时区标签 wiki,尤其是标题为“时区!=偏移”的部分。简而言之,您不能假设现在从用户那里获得的偏移量与将在任何其他时间点应用的偏移量相同。

一个简单的示例是时区,例如America/New_York,目前是 UTC-4,但在 11 月夏令时结束时将切换到 UTC-5。但除了 DST 之外,许多时区的标准时间偏移量也发生了变化。

从浏览器获取 IANA 时区标识符,而不是获取当前的数字偏移量。

const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone;
// example: "America/New_York", "Asia/Kolkata", "Europe/Athens", etc.

然后,您可以将此标识符与 PHP 的内置时区支持一起使用。例如,以下将给定时区的本地时间转换为 UTC 中的等效时间:

$tz = new DateTimeZone("America/New_York");
$date = new DateTime('2020-05-26 22:00', $tz);
$date->setTimeZone(new DateTimeZone("UTC"));
echo $date->format('Y-m-d H:i:s');
于 2020-05-28T16:49:20.130 回答