我只使用DATETIME来跟踪表中每周重复发生的事件。我只关心时间和它落在一周中的哪一天。
我需要能够将设置的DATETIME转换为当前或即将到来的未来。
IE如何使用当前日期将存储为2013-02-22 12:00:00
的日期转换为下一个事件?即下周五12:00:00或2013-03-01 12:00:00
,这样我就可以按日期订购活动了?
或者我可以将时间和一周中的某一天分别存储为数字0-6。
更新:
从欧文那里我得到了类似的东西:
Event.order("date_trunc('week', now()::timestamp) + (start_at - date_trunc('week', start_at))")
这似乎很有序,除了我得到的第一次约会是星期一,跳过我知道的星期天的活动,这是最后一次。
您的最佳选择是存储timestamp
或timestamptz
(timestamop with time zone
)。如果您已经或将来必须处理多个时区,请创建timestamptz
,并定义您是想使用当地时间还是UTC或其他时间。此相关答案中的更多详细信息:
在Rails和PostgreSQL 中完全忽略时区
演示如何有效地将时间戳转换为当前周(一周中的同一天和时间)。此处假设timestamp
:
SELECT date_trunc('week', now()::timestamp) + (t - date_trunc('week', t))
FROM (SELECT '2013-02-15 12:00:00'::timestamp AS t) x;
诀窍是计算相应周的开始和给定的timestamp
之间的interval
,并在date_trunc()
的帮助下将其添加到当前周的开始。
ISO周从周一开始,周日排在最后。
或者,只需在给定的timestamp
:上添加一周
SELECT t + interval '1 week';
如果你只想ORDER BY
,你只需要间隔:
ORDER BY (t - date_trunc('week', t))
如果你想把周日放在第一位(轮班日):
ORDER BY ((t + interval '1d') - date_trunc('week', (t + interval '1d'))
或者更简单:
ORDER BY EXTRACT(dow FROM t), t::time
引用EXTRACT()上的手册:
dow
星期日(0)至星期六(6)
isodow
的星期一(1)至星期日(7)
回答评论中的问题
我只想按当前日期订购。Ie如果是星期二,我要星期二第一,星期一最后。
"今天"午夜结束:
ORDER BY (EXTRACT(dow FROM t)::int + 7 - EXTRACT(dow FROM now())::int) % 7
,t::time
使用模运算符%
根据"今天"来转换日期
使用dow
而不是isodow
,因为从0
开始会使%
更简单。
继续使用日期时间。它很简单,给你灵活性。您可以使用提取功能来获取一天中的时间和一周中的某一天的结果。此页面将对您有所帮助。http://www.postgresql.org/docs/9.3/static/functions-datetime.html