Подтвердить что ты не робот

Oracle: вычесть миллисекунду из даты и времени

Я думал, что это действительно просто, но это не так.

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;

Почему? Как это работает?

4b9b3361

Ответ 1

Для добавления или вычитания количества времени, выраженного в виде литерала, вы можете использовать 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)

Ответ 2

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

OUTPUT

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

1 row selected.

Ответ 3

Отправленный ответ вычитает десятую часть миллисекунды с даты. Я думаю, что вы хотите следующее:

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) часа составляет десятую часть миллисекунды, а не миллисекунду. Если вы хотите использовать "ЧАС" в NUMTODSINTERVAL(), вы должны использовать 1/(60*60*1000) (шестьдесят минут в час, шестьдесят секунд в минуту, 1000 мс в секунду).

Ответ 4

Это правильно (с миллисекундой, составляющей 1000 с половиной секунды): -

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

Ответ 5

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