让这个问题成为一个调度应用程序。用户在其时区中指定的最短时间("上午8点"在" America / New_York"中),之后他们愿意接受约会。 (我们对最长时间也有类似的约束)
鉴于传入的约会请求(例如,UTC时间为2016-09-07 03:00:00
),我们需要确定哪些用户可以参加约会。
我们如何确定UTC时间戳是否在两个时区调整时间之间?
我的方法是将传入的时间戳转换为用户的时区,提取时间部分并将其与时间限制进行比较:
SELECT * FROM users u WHERE
('2016-09-07 03:00:00' AT TIME ZONE u.timezone)::time >= u.earliest_start_time AND
('2016-09-07 03:00:00' AT TIME ZONE u.timezone)::time <= u.latest_stop_time
(earliest_start_time
和latest_stop_time
属于time without time zone
; timezone
是Olson tz字符串)
由于时区偏移会导致数天翻身,因此存在各种奇怪的行为。我对这一点感到非常困惑和朦胧。
答案 0 :(得分:2)
为了使下面的代码更具可读性,假设占位符$1
包含timestamp with time zone
类型的值。然后,以下查询将查找当时可用的所有用户:
SELECT * FROM users u WHERE
$1 BETWEEN
($1::date || ' ' || u.earliest_start_time)::timestamp without time zone AT TIME ZONE u.timezone
AND
($1::date || ' ' || u.latest_stop_time)::timestamp without time zone AT TIME ZONE u.timezone;
说明:我们取$1
这是一个timestamp with time zone
,我们只保留日期部分按类型转换为date
。然后我们取earliest_start_time
这是一个时间并将其与前一个日期相结合,我们得到的时间戳没有时区信息(尚未)。然后我们指定将其转换为timestamp with time zone
的时区。我们对latest_stop_time
做同样的事情。现在我们已经找到了这两个timestamp with time zone
值,我们可以将它们与具有相同类型的$1
进行比较。
这会产生模糊时间戳的问题(即从DST到标准时间的过渡),但你无法避免这种情况。如果您只在典型的营业时间使用它,那可能没问题。