我有一个代表时间范围的表格。
Column | Type | Modifiers
-------------+-----------------------------+--------------------------------------------------------------------------
id | bigint | not null default nextval('exploded_recurring_sessions_id_seq'::regclass)
schedule_id | bigint |
start_time | time without time zone |
end_time | time without time zone |
然后我会做一个这样的查询:
select from my_table where localtime >= start_time and localtime < end_time;
这里的业务逻辑在 end_time 是午夜的情况下是有意义的,因为我认为一个范围包括 start_time 而不包括 end_time。
当然,这个查询实际上并不起作用,因为当 end_time 为 00:00:00 时,localtime 永远不会 < end_time。
我能想到两种解决方案。
- 而不是
00:00:00
,'00:00:00'::time without time zone - interval '1 microsecond'
用于午夜。这每一个导致错误计算的可能性可能低到永远不会发生。即使它确实每年发生几次,后果基本上不存在,至少就我现在的系统而言。然而,这是一个丑陋的解决方案,使用这样的错误数据可能会产生其他后果。 select from my_table where localtime >= start_time and (localtime < end_time or end_time == '00:00:00')
. 这看起来很简单,但是有必要创建一个或多个特殊索引。如果它是唯一的解决方案,这不是问题,但如果可能的话,感觉像是一个值得避免的缺点。
还有其他方法可以解决这个问题吗?某种特殊的日期时间函数可以适应这种计算?表示数据的更好方法?
介绍
您可能要考虑
23:59:59.999
属于当天。00:00:00.000
被认为是从一天到下一天的过渡。让我解释...参考:午夜(维基百科)。
24 小时制
根据您使用的是 24 小时表示法还是 12 小时上午/下午表示法,以下信息可能同样有趣。
中午/午餐
中午不是 24 小时制的问题,因为从
11:59:59.999
到12:00:00.000
的步长12:00:00.001
对时间格式没有影响。午夜
看看午夜前后的时间,你会发现那
23:59:59.999
仍然是同一天,而00:00:00.001
属于第二天。按照这个逻辑,静态值00:00:00.000
不应该属于任何一天。这是过渡点。但是,某些 RDBMS 系统会在添加
0.001 s
到2018-03-07 23:59:59.999
.12 小时符号
中午/午餐
12 小时制的中午既不是 am也不是pm,尽管时钟会在时钟从 跳到 时立即添加
11:59:59.999
PM12:00:00.000
。Midday 实际上应该m
在静态时添加一个,看到它a.m.
被定义为ante-meridiem转换为before midday,而p.m.
post -merdiem转换为after midday。午夜
这对于午夜前后的 12 小时表示法同样有效。
11:59:59.999 p.m
已接近午夜。12:00:00.001 a.m.
就在午夜过后。12:00:00 a.m./p.m.
是午夜,正好是中午之后的 12 小时或新的中午之前。但是,大多数系统决定
a.m.
在时钟到达午夜 12 点时添加一个。例子
PostgreSQL
将毫秒添加到
timestamp
值。输入:
输出:
SQL 服务器
将毫秒添加到
datetime
值。输入:
输出:
建议
正如您在示例中看到的那样,两个经过测试的 RDBMS 系统都
00:00:00.000
将时间(在或回旋处)午夜确定为次日。如果您没有将日期与时间一起使用,请避免将其用作同一天(或)
00:00:00.000
之后的午夜的表示法。这与您的解决方案编号 1 相对应。23:59:59.999
11:59:59.999 p.m.
如果您将日期与时间一起使用,那么在将微秒添加到
2018-03-07 11:59:59.999
或2018-03-07 11:59:59.999 p.m.
完整参考列表
社区维基回答:
有什么问题
'24:00:00'::time
?24:00:00
转换为00:00:00
第二天(在 PostgreSQL 中),因此2018-03-07 24:00:00
与2018-03-08 00:00:00
.