【问题标题】:Timezone specific "Open Now" function时区特定的“立即打开”功能
【发布时间】:2015-07-21 20:42:59
【问题描述】:

我需要在我正在构建的网站上使用“现在打开”的 php 函数。看之前的question,已经建好我的mysql表了:

hours_id      INT         NOT NULL,
loc_id        INT         NOT NULL,
dow           TINYINT     NOT NULL,
open_time     TIME        NOT NULL,
close_time    TIME        NOT NULL,

然后使用:

"SELECT open_time, close_time 
 FROM opening_hours 
 WHERE dow=dayofweek(curdate()) 
   AND loc_id=:loc_id"

然后我可以确定它是否打开。我正在构建的产品是全球性的,我需要将“立即打开”与位置所在的时区相关联,而不是服务器位置或查看器位置。

我已经将国家代码和位置的纬度/经度存储在相关数据库中,所以我的想法是从中获取时区,或者提供一种方法让用户选择一个,然后修改我的 SQL不知何故。

我是否朝着正确的方向前进?你的方法是什么?

【问题讨论】:

  • 你考虑过AND NOW() between open_time AND close_time
  • @RiggsFolly 是的,但这只会将小时数与服务器时间进行比较,我需要知道某个位置是否在其时区开放,而不是服务器所在的时区(位置遍布世界)。我觉得我需要在检查 SQL 之前获取该位置的时区、存储它并调整我的服务器时间。只是不确定这是最好的方法。

标签: php mysql timezone


【解决方案1】:
  1. 阅读 time zone support in MySQL,并确保您的 mysql 数据库配置了当前时区表。定期更新。

  2. 将每个位置与指定的 IANA/Olson 时区相关联,例如 "America/Los_Angeles" 或 "Europe/London"。请参阅the list here。如果你有纬度/经度,你可以通过one of these methods查询时区。

  3. 使用 MySQL CONVERT_TZ 函数将当前 UTC 时间转换为特定区域。例如,CONVERT_TZ(UTC_TIMESTAMP(),'UTC','Asia/Tokyo')

  4. 使用转换后时间的星期几和时间来检查位置条目中的日期和范围。

另外,请注意,其他人可能会建议采用仅将 UTC 存储在数据库中的方法,或者在与“现在”值进行比较之前将所有值转换为 UTC。这些方法中的任何一种都可能在边缘情况下失败,因为 UTC 星期几不一定与每个时区的星期几相同。

另一种将起作用但需要更多努力的方法是预先确定未来一段时间内的特定 UTC 开始和停止时间(至少到下一个时间,但也许更远)。然后您可以使用 UTC 时间扫描此列表。当您有数千个或更多单独的条目要检查时,这在规模上效果更好。但在较小的规模上,通常不值得开销。

同样,您可以有一个后台进程,它只在每条记录上设置一个“现在打开”标志,但它必须不断地针对您的数据库工作,并且您永远无法检查除“现在”之外的其他时间。

【讨论】:

  • 很棒的答案,以及关于为什么不存储 UTC 的出色解释(我正在考虑这个)。我会花点时间考虑一下规模选项 - 我还没有推出,所以它可能还不值得,但与此同时,我希望有 10,000 个位置,所以也许我应该把时间放在现在。再次感谢,非常感谢。
猜你喜欢
  • 2019-06-21
  • 2021-11-09
  • 1970-01-01
  • 2016-11-09
  • 1970-01-01
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 2018-07-12
相关资源
最近更新 更多