我有一个包含三列的表 providers
(包含更多列,但在这种情况下并不重要):
starttime
,您可以联系他的开始时间。endtime
,您可以联系他的最后一小时。region_id
,提供商所在的区域。美国:加利福尼亚州、德克萨斯州等英国:英格兰、苏格兰等
starttime
和 endtime
是没有时区列的时间,但是,“间接地”,它们的值具有提供者所在区域的时区。例如:
starttime | endtime | region_id (time zone of region) | "real" st | "real" et
----------|----------|---------------------------------|-----------|-----------
03:00:00 | 17:00:00 | 1 (EGT => -1) | 02:00:00 | 16:00:00
我经常需要获取时间范围在当前服务器时间范围内的供应商列表(考虑到时区转换)。问题是时区不是“恒定的”,即它们可能会在夏令时发生变化。然而,这种变化因地区而异,并不总是同时进行:EGT <=> EGST、ART <=> ARST 等。
问题是:
1. 是否有必要使用网络服务经常更新地区的时区?有谁知道可以提供服务的网络服务吗?
2.有没有更好的方法来解决这个问题?
提前致谢。
更新
我将举一个例子来阐明我想要得到的东西。在表 providers
中,我找到了这条记录:
idproviders | starttime | endtime | region_id
------------|-----------|----------|-----------
1 | 03:00:00 | 17:00:00 | 23 (Texas)
2 | 04:00:00 | 18:00:00 | 23 (Texas)
如果我在一月份执行查询,使用以下信息:
- 服务器时间(UTC 偏移量)= 0 小时
- 德克萨斯提供商(UTC 偏移量)= +1 小时
- 服务器时间 = 02:00:00
我应该得到以下结果:idproviders = 1
如果我在 6 月执行查询,并使用以下信息:
- 服务器时间(UTC 偏移量)= 0 小时
- 德州供应商(UTC 偏移)= +2 小时(他们的本地时间没有改变,但他们的时区已经改变)
- 服务器时间 = 02:00:00
我应该得到以下结果:idproviders = 1 and 2
最佳答案
除了它们具有 ID 之外,您还没有提供有关您的“区域”记录的任何详细信息。
不过,您可以将一列 timezone varchar NOT NULL
添加到您的 regions
表(我假设您有一个)。您需要分配一个 time zone name到您拥有的每个区域。这可能不是一项简单的任务。
执行此操作后,您可以使用以下查询找到哪些提供商在营业时间内:
SELECT p.* FROM providers AS p LEFT JOIN regions AS r ON (r.id = p.region_id)
WHERE (now() AT TIME ZONE r.timezone)::time BETWEEN p.start_timestamp AND p.end_timestamp;
now() AT TIME ZONE r.timezone
会将当前服务器时间转换为分配给该地区的时区。
示例设置:您的服务器在伦敦,您的提供商在巴拿马。
示例案例 1:您的服务器时间是 2012-01-01 18:00:00。 '2012-01-01 18:00:00' AT TIME ZONE 'America/Panama'
将返回 2012-01-01 13:00:00
,当前时间在巴拿马,您可以将其与提供商的 start_timestamp
和 end_timestamp
进行比较。
案例 2:您的服务器时间是 2012-08-01 18:00:00,您遵守 DST。然而,巴拿马不遵守夏令时,因为它靠近赤道并且日长变化不大。不过,'2012-08-01 18:00:00' AT TIME ZONE 'America/Panama'
将返回巴拿马的正确当前时间:2012-08-01 12:00: 00
,因为 Postgres 知道您在八月的时间遵守夏令时,而巴拿马的时间没有。
我不知道如何让你更清楚。
关于php - 获取 "dynamic"时区之间的等效时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12476178/