活动有很多变化。
我的班次表包含starts_at
和ends_at
列,这些列是DATETIME格式。
如果我查询轮班表,starts_at
和ends_at
列将返回一个包含时区信息的字符串,并被Rails识别为ActiveSupport::TimeWithZone
对象 - 我可以操作它相应
如果我在涉及联接的更复杂查询中包含shifts.starts_at
或shifts.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")
产地:
+-----+----------+---------------------+---------------------+ | id | shift_id | starts_at | ends_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将它们识别为String数据。数据以UTC格式存储在数据库中。如果我在同一查询中包含datetime
表中的events
列,则会在结果中包含时区数据。
我一直在搜索文档,试图了解这里发生了什么,但无济于事。
答案 0 :(得分:2)
我想你应该首先掌握所涉及的数据类型。 PostgreSQL中的“datetime”数据类型实际上是timestamp
and there are two variants: with
and without time zone
。默认值为without
。
在内部,PostgreSQL始终存储UTC时间戳。时区数据本身不保存所有时间戳,无论是否有时区。这些只是输入和输出的装饰器,适用于客户端的时区设置。
查找更多detailed explanation, examples and links at this related answer。
答案 1 :(得分:0)
我想如果你把starts_at :: timestamptz放进去,那么你就是好人。