我已经被困在这两天了,并且没有在哪里。我倾向于认为未来和未来会出现问题。我的服务器时间设置为UTC,并且linux box已完全使用时区更新,数据也在我的数据库中。
我将解释我的系统以获得最佳答案。
此网站销售“商品”,但只能在营业时间和关闭时间内销售。商店可以分开工作时间:即:开放时间为上午8点至下午12点,下午1点至晚上8点......等等。
所以我的小时表看起来像:
id (1) | store_id (1) | opens (08:00) | closes (21:00)
上面有列名旁边的示例数据。商店ID#1基本上可以在洛杉矶(美国/太平洋地区),也可能在纽约市(美国/东部)。
确保我不会错过一小时的停机时间的最佳方法是什么,这样我就可以禁止用户在下班时间从这些商店订购。如果我离开时间一小时,那是一个小时没有人可以在他们真正开放时订购,一小时用户会在他们真正关闭时订购..反之亦然,具体取决于时间的变化。
有没人处理过这件事?如果是这样,你是怎么做到的?
解决此问题的最佳方式是什么?我一直在处理它,它在过去的48小时内正在吃掉我的大脑。
请帮忙! :)
答案 0 :(得分:0)
要记住的一件事是,有些地方(想想亚利桑那州)不做DST。您可能希望确保您的数据库具有足够的信息,以便您可以在必要时区分LA和Phoenix。
假设您遵循ITroubs的建议,并在数据库中放置偏移量(以及可能有关商店是否属于DST尊重语言环境的信息),您可以执行以下操作:
构建代码,以便检查DST是否生效,并适当地构建查询。如果您的所有商店都在纽约和洛杉矶,那么您可以在需要时将偏移量加1。如果没有,您将需要一个查询,该查询对DST和非DST存储使用不同的规则。像,
SELECT store_id
FROM hours
WHERE
(supportsDST = true AND opens < dstAdjustedNow AND closes > dstAdjustedNow)
OR (supportsDST = false AND opens < UTCNow AND closes > UTCNow)
如果你选择这条路线,我建议尽可能集中并隔离处理此问题的代码。
另外,你没有提到这一点,但是我假设一个具有分割时间的商店在小时表中会有两行,每一个用于打开的一行。
答案 1 :(得分:0)
在Postgres和MySQL中实际上很容易实现。您所要做的就是将时区存储在用户端,将服务器TZ设置为UTC,然后在两者之间进行转换。
EX:
SELECT
CASE WHEN (
(CAST((CURRENT_TIMESTAMP at time zone s.timezone) as time) BETWEEN h.opens AND h.closes) AND
h.day = extract(dow from CURRENT_TIMESTAMP at time zone s.timezone)) THEN 0 ELSE 1 END
) as closed
FROM store s
LEFT JOIN store_hours r ON s.id = r.store_id
HERE h.day = extract(dow from CURRENT_TIMESTAMP at time zone s.timezone)
它就是这样的。我必须以这种方式进行类型转换,因为我使用Doctrine 1.2是有限的。
即使有DST更改,也可以像魅力一样。