1

事件有很多变化。

我的班次表包含一个日期时间格式的列starts_atends_at

如果我查询班次表,starts_atandends_at列返回一个包含时区信息的字符串,Rails 将其识别为一个ActiveSupport::TimeWithZone对象——我可以相应地对其进行操作。

如果我在涉及连接的更复杂的查询中包含shifts.starts_atorshifts.ends_at列,我似乎会丢失结果集中的时区信息。考虑以下查询:

SELECT events.id, events.name, events.default_shift_start,
shifts.id AS shift_id, shifts.starts_at, shifts.ends_at, users.id AS user_id,
users.first_name, users.last_name 
FROM "events" 
INNER JOIN "shifts" ON "shifts"."event_id" = "events"."id" 
INNER JOIN "requests" ON "requests"."shift_id" = "shifts"."id" 
INNER JOIN "users" ON "users"."id" = "requests"."user_id" 
WHERE (events.default_shift_start > '2012-08-22 05:55:22.069340' AND requests.status = 'accepted') 
ORDER BY default_shift_start ASC

编辑:我在 Rails 中通过以下方式调用此查询:

Event.joins(:shifts => { :requests => :user}).where(["events.default_shift_start > ? AND requests.status = ?", Time.now, "accepted"]).select("events.id, events.name, events.default_shift_start, shifts.id AS shift_id, shifts.starts_at, shifts.ends_at, users.id AS user_id, users.first_name, users.last_name").order("default_shift_start ASC")

产生:

+-----+---------+---------+---------- ------------+
| 编号 | shift_id | 开始时间 | end_at |
+-----+---------+---------+---------- ------------+
| 17 | 80 | 2012-08-23 00:30:00 | 2012-08-23 07:30:00 |
| 17 | 55 | 2012-08-23 00:30:00 | 2012-08-23 07:30:00 |
+-----+---------+---------+---------- ------------+

问题是 JOINed 表 ( shifts) 中的列没有返回任何时区数据,导致 Rails 将它们识别为字符串数据。数据以 UTC 格式存储在数据库中。如果我在同一个查询中包含表中的一datetime列,它会在结果中包含时区数据。events

我一直在搜索文档,试图了解这里发生了什么,但无济于事。

4

2 回答 2

2

我想你应该从掌握所涉及的数据类型开始。PostgreSQL 中的“日期时间”数据类型实际上timestamp有两种变体:withwithout time zone. 默认值为without.

在内部,PostgreSQL 总是存储一个 UTC 时间戳。时区数据本身根本使用时间戳保存,无论是否有时区。这些只是适应客户端时区设置的输入和输出装饰器。

在此相关答案中找到更详细的解释、示例和链接

于 2012-08-22T06:26:11.970 回答
0

我认为如果您输入starts_at::timestamptz,那么您就很好。

于 2012-08-22T08:16:04.250 回答