确定UTC时间戳是否在时区的时间范围内?

Determining whether a UTC timestamp is within a time range in a timezone?

让我们将这个问题定义为一个调度应用程序。用户在他们的时区("America/New_York" 中为“上午 8 点”)指定最短时间 ,之后他们愿意接受预约。 (我们对最长时间也有类似的限制)

给定传入的约会请求(例如,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_timelatest_stop_time 属于 time without time zone 类型;timezone 是 Olson tz 字符串)

由于时区偏移导致日子倒流,因此有各种奇怪的行为,我对此通常感到非常困惑和模糊。

为了使下面的代码更具可读性,假设占位符 </code> 包含类型 <code>timestamp with time zone 的值。然后下面的查询将找到当时可用的所有用户:

SELECT * FROM users u WHERE
     BETWEEN
      (::date || ' ' || u.earliest_start_time)::timestamp without time zone AT TIME ZONE u.timezone
    AND
      (::date || ' ' || u.latest_stop_time)::timestamp without time zone AT TIME ZONE u.timezone;

说明:我们采用 </code>,这是一个 <code>timestamp with time zone,我们只保留日期部分,将其类型转换为 date。然后我们取 earliest_start_time 这是一个时间并将它与前一个日期结合起来,我们得到没有时区信息的完整时间戳(还)。然后我们指定时区将其转换为 timestamp with time zone。我们对 latest_stop_time 做同样的事情。所以现在我们已经找到了那 2 个 timestamp with time zone 值,我们可以将它们与具有相同类型的 进行比较。

尽管时间戳不明确(即从夏令时到标准时间的转换)会有问题,但您无法避免。如果您只在正常工作时间使用它,可能没问题。