确定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_time
和 latest_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
值,我们可以将它们与具有相同类型的
进行比较。
尽管时间戳不明确(即从夏令时到标准时间的转换)会有问题,但您无法避免。如果您只在正常工作时间使用它,可能没问题。
让我们将这个问题定义为一个调度应用程序。用户在他们的时区("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_time
和 latest_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
值,我们可以将它们与具有相同类型的 进行比较。
尽管时间戳不明确(即从夏令时到标准时间的转换)会有问题,但您无法避免。如果您只在正常工作时间使用它,可能没问题。