23

我以为这很简单,但事实并非如此。

SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY') 
          - 1/(24*50*60*1000) data 
FROM dual;

它根本行不通。


其他详情:

SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY') -
           NUMTODSINTERVAL(1/(24*50*60*1000),'HOUR') data 
FROM dual;

不行。。

权利似乎是

SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY') -
           NUMTODSINTERVAL(1/(24*25*60*1000),'HOUR') data 
FROM dual;

为什么?它是如何工作的?

4

5 回答 5

31

要添加或减去以文字形式表示的时间量,您可以使用 INTERVAL。

SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY')
     - INTERVAL '0.001' SECOND 
FROM dual;

现在也有标准的方法来表达日期和时间文字并避免使用各种数据库特定的转换函数。

SELECT TIMESTAMP '2012-10-08 00:00:00' 
   - INTERVAL '0.001' SECOND DATA
FROM dual;

对于您的原始问题,一天中的时间部分以小数天数存储。所以一秒钟是:

1 / (hours in day * minutes in hour * seconds in a minute)

除以 1000 得到毫秒。

1 / (24 * 60 * 60 * 1000)
于 2012-09-07T00:23:27.377 回答
11
SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY') - NUMTODSINTERVAL(1/(24*50*60*1000),'HOUR') data 
FROM dual;

输出

DATA                             
---------------------------------
09/AUG/12 11:59:59.999950000 PM  

1 row selected.
于 2012-08-10T11:21:43.420 回答
9

上面发布的答案从日期中减去了十分之一毫秒。我认为您想要的是以下内容:

SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY')-NUMTODSINTERVAL(1/1000,'SECOND')
  FROM dual;

输出:

DATA
---------------------------------------------------------------------------
09-AUG-12 11.59.59.999000000 PM
                   ^^^
                   |||
              tenths|thousandths
                    |
                hundredths

以下NUMTODSINTERVAL(1/(24*25*60*1000),'HOUR')似乎仅因为 24*25 = 600 才有效。但这个数字是错误的,因为一小时的 1/(600*60*1000) 是十分之一毫秒,而不是毫秒。如果你想使用'HOUR',NUMTODSINTERVAL()你应该使用1/(60*60*1000)(一小时六十分钟,一分钟六十秒,一秒1000毫秒)。

于 2012-09-06T12:54:06.577 回答
7

这是正确的(毫秒是千分之一秒):-

SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY') - NUMTODSINTERVAL(1/1000,'SECOND') data FROM dual;


DATA
-----------------------------
09-AUG-12 23.59.59.999000000

至于为什么其他代码不起作用,是因为您没有正确计算毫秒。一个小时必须除以 60 给出分钟,再除以 60 给出秒,然后再除以 1000 给出毫秒,因此如果你必须使用 HOUR 作为间隔,那么它是:-

SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY') - NUMTODSINTERVAL(1/(60*60*1000),'HOUR') as data FROM dual;

DATA
---------------------------------------------------------------------------
09-AUG-12 23.59.59.999000000
于 2012-09-06T12:44:07.493 回答
2
select TO_CHAR(TO_TIMESTAMP('10.05.2012', 'DD.MM.YYYY') - 
       NUMTODSINTERVAL(1/1000, 'SECOND'), 'DD.MM.YYYY HH24:MI:SS:FF3')  Res 
  from dual;

RES
-----------------------------
09.05.2012 23:59:59.999
于 2012-09-06T13:57:03.253 回答