我有一个表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)
如果我在1月份执行查询,请输入以下信息:
我应该得到以下结果: idproviders = 1
如果我在六月份执行查询,请输入以下信息:
我应该得到以下结果: idproviders = 1和2
答案 0 :(得分:2)
您还没有任何有关您的"地区的详细信息"记录除了他们有身份证明之外。
但是,您可以在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知道您8月份的时间是DST,而巴拿马的时间不是。
我不知道如何让它更清楚。
答案 1 :(得分:1)
如果你只有一个time
(而不是timestamp
)和一个像“德克萨斯”这样的地区,那么你开始时运气不好。是否应该是夏令时的信息不存在。你不可能知道。
即使您只使用timestamptz
组件,也要将该字段设为timestamp with time zone
(time
)。因此,只要有人输入一个值,就会在内部将其转换为UTC时间戳(自动将DST考虑在内)并且您拥有明确的信息。该值将根据当前时区设置自动显示(适用于所有人),适合所有人。测试时,您可以简单地将它投射到时间:
SELECT start_timestamp::time
它为您提供等效的 local time
(根据您当前的时区设置)。让一切变得非常轻松
更多解释PostgreSQL如何处理this related answer中的时间戳。