2

如果不清楚,请原谅我,但我很难将我的想法写在纸上。

设想:

我们将各种作业存储在一个表中。这些都使用设置为 UTC 时区的 DATETIME 加上时间戳。

我们的用户可能会在他们的偏好中设置他们的时区,以便我们可以将系统时间转录为用户本地时间。

现在,假设用户选择了 2012 年 10 月 25 日(本地用户时间)输入的所有作业:

+--------------------------------------+------------+---------+---------------------+
| id                                   | project_id | amount  | created             |
+--------------------------------------+------------+---------+---------------------+
| 50889ba5-77b4-41e1-a942-1dea0ab761f6 |   15076850 |   50.00 | 2012-10-25 01:53:41 |
| 5088b9a3-8110-446e-81c8-75da341f3f95 |   15076850 | 2000.00 | 2012-10-25 04:01:39 |
| 5088c852-d434-41e6-ba5d-27560ab761f6 |   15076850 |  100.00 | 2012-10-25 05:04:18 |
| 50892a3b-ad9c-4a32-aebf-384c0ab761f6 |   15076850 |  500.00 | 2012-10-25 12:02:03 |
| 50893098-6b9c-4028-9a87-3eb20ab761f6 |   15076850 |   25.00 | 2012-10-25 12:29:12 |
| 50894b10-d260-4f61-8eb9-1d190ab761f6 |   15076850 |   25.00 | 2012-10-25 14:22:08 |
| 50895129-48c8-4bb4-928f-483b341f3f95 |   15076850 |   25.00 | 2012-10-25 14:48:09 |
| 50896019-7144-4e74-8037-4160341f3f95 |   15076850 |   50.00 | 2012-10-25 15:51:53 |
+--------------------------------------+------------+---------+---------------------+
8 rows in set (0.00 sec)

如果此用户位于美国东部 (EST),并且此表中的时间是 UTC,则表结果中的前两行的结果将是 10 月 24 日。基本上,如果用户是 EST,我想排除前两行。

我一直在尝试使用DateTime(),但是 - 我被卡住了,因为它跨越了 DST 结束(2012 年 11 月 4 日)。当我选择 10 月 25 日的日期时,DST 处于活动状态,因此它将用户本地时间显示为 UTC -0400。当作业结束时,它是在 (UTC -0500) 之后。

我完全坚持如何使这项工作。

4

1 回答 1

3

获取用户午夜的 UTC 时间戳(在以下示例中为凌晨 4 点 UTC):

$start = new DateTime('2012-10-25 00:00:00', new DateTimeZone('America/New_York'));
$start->setTimeZone(new DateTimeZone('UTC'));
$start = $start->format('Y-m-d H:i:s');

// do the same with $end

SELECT ... WHERE `created` BETWEEN $start AND $end

最终查询应选择WHERE BETWEEN 2012-10-25 04:00:00 AND 2012-10-26 03:59:59,即美国/纽约的 10 月 25 日这一天。

这也应该在 DST 更改期间起作用。在 11 月 4 日,查询将是BETWEEN 2012-11-04 04:00:00 AND 2012-11-05 04:59:59,再包含一个小时。

于 2012-12-12T07:36:02.200 回答