Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Nagaraju.

Asked: May 16, 2001 - 11:22 am UTC

Last updated: September 28, 2008 - 9:36 am UTC

Version: 8.1.6

Viewed 10K+ times! This question is

You Asked

how do i add a millisecond to a date.
i only have calculate(24/(60 * 60 *1000) and add) or is there any other way?

thanks
nagaraju

and Tom said...

you cannot. dates only have seconds. adding a millisecond will not affect what is stored. It would be like adding .001 to an integer - -nothing.

Rating

  (8 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

How do I get the ONLY ' the Millisec ' from MY_TIMESTAMP

Pascal, February 20, 2002 - 11:36 am UTC

Hi Tom,
Thanks for My_Timestamp JSP.

I have tried to Exract only the Millisec part , but you can see from the Query below that there's some LAG ...now , how do i Extract only the Millisec without this LAG.


column my_timestamp format a30
column millisec format a30
select substr(my_timestamp,instr(my_timestamp,'.')+1 ) millisec , my_timestamp from dual;


MILLISEC MY_TIMESTAMP
------------------------------ -----------------------------
594 2002-02-20 19:34:26.596


Thanks in advance


Best Regards


Pascal


Tom Kyte
February 22, 2002 - 10:12 am UTC

ops$tkyte@ORA817DEV.US.ORACLE.COM> CREATE or replace JAVA SOURCE
  2  NAMED "MyTimestamp"
  3  AS
  4  import java.lang.String;
  5  import java.sql.Timestamp;
  6  
  7  public class MyTimestamp
  8  {
  9      public static String getTimestamp()
 10      {
 11        return (new
 12           Timestamp(System.currentTimeMillis())).toString();
 13      }
 14  };
 15  /

Java created.


ops$tkyte@ORA817DEV.US.ORACLE.COM> create or replace function my_timestamp return varchar2
  2  AS LANGUAGE JAVA
  3  NAME 'MyTimestamp.getTimestamp() return java.lang.String';
  4  /

Function created.

ops$tkyte@ORA817DEV.US.ORACLE.COM> column my_timestamp format  a30
ops$tkyte@ORA817DEV.US.ORACLE.COM> column       millisec format  a30
ops$tkyte@ORA817DEV.US.ORACLE.COM> column       ts format  a30

ops$tkyte@ORA817DEV.US.ORACLE.COM> select       substr(my_timestamp,instr(my_timestamp,'.')+1 ) millisec , my_timestamp
  2  from dual;

MILLISEC                       MY_TIMESTAMP
------------------------------ ------------------------------
148                            2002-02-22 10:10:42.152

ops$tkyte@ORA817DEV.US.ORACLE.COM> select substr(ts,instr(ts,'.')+1 ) millisec , ts
  2  from (select my_timestamp ts, rownum r from dual);

MILLISEC                       TS
------------------------------ ------------------------------
166                            2002-02-22 10:10:42.166


using rownum in the inline view is a "trick", we evaluate the inline view once and then apply the outer select to it -- hence my_timestamp is called only once and its results are used twice. 

A reader, August 30, 2002 - 7:44 pm UTC

Hi Tom,

In 9i R2 oracle has new datatype Timestamp.
Can it store millisecond?

Can you explain with example?

Thanks,

Tom Kyte
August 30, 2002 - 8:12 pm UTC

It is 9i Release 1 that added this feature.

ops$tkyte@ORA920.US.ORACLE.COM> create table t
  2  ( x timestamp,
  3    y timestamp with time zone );

Table created.

ops$tkyte@ORA920.US.ORACLE.COM>
ops$tkyte@ORA920.US.ORACLE.COM> insert into t values ( systimestamp, systimestamp );
1 row created.

ops$tkyte@ORA920.US.ORACLE.COM>
ops$tkyte@ORA920.US.ORACLE.COM> select * from t;

X
---------------------------------------------------------------------------
Y
---------------------------------------------------------------------------
30-AUG-02 08.15.53.195414 PM
30-AUG-02 08.15.53.195414 PM -04:00




supports not only fractional seconds but timezones as well if you like. 

limited

Christo Kutrovsky, September 30, 2003 - 5:13 pm UTC

Hi Tom,

I was trying to use timestamp, to gradually replace some of my DATE types, due to more precision and easily used with the interval datatype (timetsamp - timestamp = interval).

However, I find that it is pretty limited, in terms of provided built-in functions.

trunc(timestamp) To get the day only does not work (for group by for example)

round(timestamp) also does not work.

The same applies to the interval datatype. I intended to replace my NUMBER fields which holded a number of "seconds" with the new INTERVAL DAY TO SECOND datatype, but then I loose the ability to round to a minute for example. (which is as easy as round(seconds/60))

Also converting from INTERVAL DAY TO SECOND to get for example "55 hours , 33 minutes and 13 seconds" instead of "2 days, 7 hours, 33 minutes and 13 seconds" requires lot's of code.

Are any of those issues addressed in the upcoming Oracle 10G ?


Tom Kyte
October 01, 2003 - 7:41 am UTC

ops$tkyte@ORA920> l
  1*  select localtimestamp, trunc(cast( localtimestamp as date)) from dual
ops$tkyte@ORA920> /
 
LOCALTIMESTAMP               TRUNC(CAST(LOCALTIME
---------------------------- --------------------
01-OCT-03 07.41.03.387167 AM 01-oct-2003 00:00:00


  1* select localtimestamp, round(cast( localtimestamp as date)) from dual
ops$tkyte@ORA920> /
 
LOCALTIMESTAMP               ROUND(CAST(LOCALTIME
---------------------------- --------------------
01-OCT-03 07.41.20.393160 AM 01-oct-2003 00:00:00


as for the interval type -- how it works, behaves, is dictated by ANSI -- we just implemented the "standard" 

Intersting.

Christo Kutrovsky, October 01, 2003 - 10:18 am UTC

Interesting.

Does the cast involve any perfomance issues ?

It will be so more convenient if trunc/round supported (and transperently) converted timestamp.

Are there plans to extend the interval "ansi" datatype?


Tom Kyte
October 01, 2003 - 1:41 pm UTC

well, without cast, it doesn't work :)

so performance aside -- we cannot really compare cast vs no cast

i'm not aware of any changes -- but there is alot of stuff to look at still in 10


Ora-29540: class MyTimestamp does not exist

Shaji, June 30, 2005 - 5:35 pm UTC

Hi Tom,

I wanted to use the MyTimestamp function in one of the requirements. And I created exactly as you mentioned. When I call that function I get the following error
ERROR at line 1:
ORA-29540: class MyTimestamp does not exist

I checked the function in all_objects and it's valid. Am I missing something?This is my first Java store proc.

I am using SQl client version of 9.2.0.1.0 and Database 9.2.0.4.0 .
Thanks in advance

Tom Kyte
June 30, 2005 - 5:58 pm UTC

cut and paste just like I do, MyTimestamp is OUR class, the one WE made, if it "doesn't exist", it must be a typo somewhere.

timestamp

A reader, September 26, 2008 - 8:48 am UTC

tom:

When do you use "timestamp" field type versus "date" field?

If you want an audit column of when the record was created do you use "date" usually.

The only issue that might occur with "date" when you useMAX to find the last record entered. A few records may have ben saved in the same second.


Tom Kyte
September 26, 2008 - 1:16 pm UTC

do you have a need for fractional seconds or timezone support - if so, timestamp.


If you just need the date and time down to the second - date does it.


using MAX won't work with timestamps either - since I might insert a record, you insert a record after me, you commit, then I commit.

I am the newest record really - but you cannot tell that.

And, even with timestamps, there are chances of duplicates - you cannot rely on a timestamp being unique.

timestamp

A reader, September 26, 2008 - 10:49 pm UTC

Tom:

yes but the chances of two records with same timestamp are much less thatn two date records.

It seems the best thing is to use sequence number (this will only work with one instance with one seq generator) or filter one of the records with same timestamps.

What do you recommend?
Tom Kyte
September 27, 2008 - 11:35 am UTC

... yes but the chances of two records with same timestamp are much less thatn two
date records.
...

so what? This is a binary thing, either

a) there is no chance
b) there is a chance

If there is a chance and you are not prepared to deal with it - then so what, THERE IS A CHANCE. I don't care if it is smaller, it exists, that is all that counts here.

As to what is recommended - what makes sense to you, what meets your requirements.

(me, I'd use a sequence to unique identify records, but you can still have the situation whereby:

a) I use seq.nextval and get the number 42
b) you use it and get 43
c) you commit - your record exists, mine does not
d) I commit - my record exists now for the first time

My record is newer than yours but will look older - but - does that matter to you... If it does - then you need to do something about it - but only you can say what that is, you must have some rule to tell us how to deal with that)

timestamp

A reader, September 27, 2008 - 11:54 am UTC

Tom:

I see what you are saying. But can this case really happen when the sequence is fetched in the insert statement and followed by a commit. I would think the first person who gets 42 will be committed before the next one who got 43 unless there is something internal i am not aware of.

USER A
=======
insert into T values (seq.nextval...)
commit;

USER B
---------
insert into T values (seq.nextval...)
commit;
Tom Kyte
September 28, 2008 - 9:36 am UTC

... But can this case really happen when the sequence is
fetched in the insert statement and followed by a commit. I would think the
first person who gets 42 will be committed before the next one who got 43
unless there is something internal i am not aware of.
...


think about what happens on a multi-user computer. Things get pre-empted, blocked, scheduled, bumped on and off cpu's.

Also, think about multi-user concurrency issues, more complex transactions. For example - suppose User-A does more than just insert into T, they insert into T and then do something else and then commit. Heck, keep the example as simple as it is - but add a third person to the mix

drop table t;
drop sequence s;

create table t
( x int primary key, y int unique, z timestamp, msg varchar(20) );
create sequence s;

insert into t values ( s.nextval, 0, systimestamp, 'sess 1' );
set echo off
prompt SESSION 2:
prompt insert into t values ( s.nextval, 0, systimestamp, 'sess 2' );;
prompt commit;;
prompt SESSION 3:
prompt insert into t values ( s.nextval, 1, systimestamp, 'sess 3' );;
prompt commit;;
prompt THEN COME BACK AND HIT ENTER
pause
rollback;
exec dbms_lock.sleep(1);
select * from t;


session 1 blocks session 2, session 3 comes in after session 2 and creates their row and commits, when 1 rolls back, 2 commits.

Now, as I said - whether this 'matters' or not to you is something only you can answer - but there are millions of ways for a row to be created - a transaction to get blocked, pre-empted, paused - and another transaction to come in and do stuff.

Do not think linear here, things happen more or less simultaneously