时区特定 "Open Now" 函数

Timezone specific "Open Now" function

我需要在我正在构建的网站上使用 'is open now' php 功能。看看之前的question,我构建了我的mysql table:

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"

然后我可以计算它是否打开。我正在构建的产品是全球性的,我需要 'open now' 与位置所在的时区相关,而不是服务器位置或观众位置。

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

我的方向是否正确?你的方法是什么?

  1. 阅读有关 time zone support in MySQL 的信息,并确保您的 mysql 数据库配置有当前时区表。定期更新。

  2. 将每个位置与命名的 IANA/Olson 时区相关联,例如 "America/Los_Angeles""Europe/London"。参考the list here. If you have lat/lon, you can look up the time zone via one of these methods.

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

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

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

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

同样,你可以有一个后台进程,它只在每条记录上设置一个 "now open" 标志,但它必须不断地对你的数据库进行操作,并且你永远无法检查 "now".