Joh*_*hir 3 postgresql datetime time
我有一个代表时间范围的表格。
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 |
Run Code Online (Sandbox Code Playgroud)
然后我会做一个这样的查询:
select from my_table where localtime >= start_time and localtime < end_time;
Run Code Online (Sandbox Code Playgroud)
在 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 小时制还是 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 小时表示的正午既不是 am也不是pm,即使时钟会在时钟从 跳转11:59:59.999
到 时立即添加 PM 12:00:00.000
。中午实际上应该m
在静态时添加一个单一的,看到它a.m.
被定义为ante-merdiem,它转换为正午之前,而p.m.
这是后午后转换为正午之后。
这对于午夜前后的 12 小时表示法同样有效。11:59:59.999 p.m
已接近午夜。12:00:00.001 a.m.
就在午夜过后。12:00:00 a.m./p.m.
是午夜,正好是中午之后或新中午之前的 12 小时。
但是,大多数系统决定a.m.
在时钟到达午夜 12 点时立即添加一个。
向timestamp
值添加毫秒。
postgres=# select TIMESTAMP '2018-03-07 23:59:59.999' + interval '1 ms';
Run Code Online (Sandbox Code Playgroud)
2018-03-08 00:00:00
Run Code Online (Sandbox Code Playgroud)
向datetime
值添加毫秒。
select dateadd(ms,001,cast('2018-03-07 23:59:59.999' as datetime))
Run Code Online (Sandbox Code Playgroud)
2018-03-08 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
正如您在示例中看到的那样,两个经过测试的 RDBMS 系统都确定00:00:00.000
是午夜时间(之后或回旋处),但在第二天。
如果您不将日期与时间一起使用,请避免将其00:00:00.000
用作同一天之后23:59:59.999
(或11:59:59.999 p.m.
)午夜的表示法。这对应于您的解决方案编号 1。
如果您使用的日期与时代一起,然后找出你的符号RDBMS支持加时一微秒要么2018-03-07 11:59:59.999
或2018-03-07 11:59:59.999 p.m.