We are using Oracle database.
In our table timestamp is stored as seconds since 1970, how can I convert the time stamp obtained through current_timestamp() function to seconds
This would do it:
select round((cast(current_timestamp as date) - date '1970-01-01')*24*60*60) from dual
Though I wouldn't use current_timestamp if I was only interested in seconds, I would use SYSDATE:
select round((SYSDATE - date '1970-01-01')*24*60*60) from dual
Maybe not completely relevant. I had to resolve other way around problem (e.g. Oracle stores timestamp in V$RMAN_STATUS and V$RMAN_OUTPUT) and I had to convert that to date/timestamp. I was surprised, but the magic date is not 1970-01-01 there, but 1987-07-07. I looked at Oracle's history and the closest date I can think of is when they ported Oracle products to UNIX. Is this right?
Here's my SQL
SELECT /*+ rule */
to_char(min(stamp)/(24*60*60) + date '1987-07-07', 'DD-MON-YYYY HH24:MI:SS') start_tm
, to_char(to_char(max(stamp)/(24*60*60) + date '1987-07-07', 'DD-MON HH24:MI:SS')) end_tm
FROM V$RMAN_STATUS
START WITH (RECID, STAMP) =
(SELECT MAX(session_recid),MAX(session_stamp) FROM V$RMAN_OUTPUT)
CONNECT BY PRIOR RECID = parent_recid ;
I needed to send timestamp to GrayLog via GELF from Oracle DB. I tried different versions and solutions but only one worked correctly.
SQL:
SELECT REPLACE((CAST(dat AS DATE) - TO_DATE('19700101', 'YYYYMMDD')) * 86400 + MOD(EXTRACT(SECOND FROM dat), 1), ',', '.') AS millis
FROM (SELECT SYSTIMESTAMP AT TIME ZONE 'GMT' AS dat FROM dual)
The result for Systmiestamp
2018/12/18 19:47:29,080988 +02:00
will be
1545155249.080988
Related
I am trying to separate the time and date in one column to be independent off each other. I am new at writing scripts
this is my query:
select
*
from
[tablename]
where
to_date([column_name]) in ( '15-Jun-2021', '16-Jun-2021' )
and
to_char([column_name],'dd-Mon-yyyy HH:MM:ss') < '15-Jun-2021 19:54:30'
The way you put it, it would be
select *
from your_table
where date_column >= date '2021-06-15'
and date_column < to_date('15.06.2021 19:54:30', 'dd.mm.yyyy hh24:mi:ss')
because
date_column should be of date datatype. If it isn't, you'll have problems of many kinds in the future. Therefore,
don't to_date it, it is already a date
don't to_char it either, because you'd be comparing strings and get unexpected result. Use that function when you want to nicely display the result
the second condition you wrote makes the first one questionable. If date_column is less than value you wrote, then you can omit date '2021-06-16' from the first condition because you won't get any rows for that date anyway
date literal (date '2021-06-15') sets time to midnight, so condition I wrote should return rows you want
SQL> select date '2021-06-15' first,
2 to_date('15.06.2021 19:54:30', 'dd.mm.yyyy hh24:mi:ss') second
3 from dual;
FIRST SECOND
------------------- -------------------
15.06.2021 00:00:00 15.06.2021 19:54:30
SQL>
Was wondering if anyone could help with precision time conversion.
Sample: 1501646399999 which is GMT: Wednesday, August 2, 2017 3:59:59.999 AM
I used the below query, but it always rounds off to 02-AUG-17 04:00:00. Can anyone please guide me
select TO_TIMESTAMP('1970-01-01 00:00:00.000', 'YYYY-MM-DD hh24:mi:SS.FF3') + ((1/86400000) * 1501646399999)
from dual;
The problem is that you're adding a number to your fixed timestamp, which is causing that timestamp to be implicitly converted to a date - which doesn't have sub-second precision.
If you add an interval instead then it stays as a timestamp:
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS.FF3';
select TO_TIMESTAMP('1970-01-01 00:00:00.000', 'YYYY-MM-DD hh24:mi:SS.FF3')
+ numtodsinterval(1501646399999/1000, 'SECOND')
from dual;
TO_TIMESTAMP('1970-01-0
-----------------------
2017-08-02 03:59:59.999
Incidentally, you could slightly simplify your query with a timestamp literal:
select TIMESTAMP '1970-01-01 00:00:00' + numtodsinterval(...)
You may also want to check if you should be declaring that timestamp as being UTC, and converting back to local time zone after adding the epoch value; or leaving it explicitly as UTC but as a timestamp with time zone value. It depends exactly what that number is supposed to represent. (You said it's GMT/UTC, but still...)
I need to query 2 tables, one contains a TIMESTAMP(6) column, other contains a DATE column. I want to write a select statement that prints both values and diff between these two in third column.
SB_BATCH.B_CREATE_DT - timestamp
SB_MESSAGE.M_START_TIME - date
SELECT SB_BATCH.B_UID, SB_BATCH.B_CREATE_DT, SB_MESSAGE.M_START_TIME,
to_date(to_char(SB_BATCH.B_CREATE_DT), 'DD-MON-RR HH24:MI:SS') as time_in_minutes
FROM SB_BATCH, SB_MESSAGE
WHERE
SB_BATCH.B_UID = SB_MESSAGE.M_B_UID;
Result:
Error report -
SQL Error: ORA-01830: date format picture ends before converting entire input string
01830. 00000 - "date format picture ends before converting entire input string"
You can subtract two timestamps to get an INTERVAL DAY TO SECOND, from which you calculate how many minutes elapsed between the two timestamps. In order to convert SB_MESSAGE.M_START_TIME to a timestamp you can use CAST.
Note that I have also removed your implicit table join with an explicit INNER JOIN, moving the join condition to the ON clause.
SELECT t.B_UID,
t.B_CREATE_DT,
t.M_START_TIME,
EXTRACT(DAY FROM t.diff)*24*60 +
EXTRACT(HOUR FROM t.diff)*60 +
EXTRACT(MINUTE FROM t.diff) +
ROUND(EXTRACT(SECOND FROM t.diff) / 60.0) AS diff_in_minutes
FROM
(
SELECT SB_BATCH.B_UID,
SB_BATCH.B_CREATE_DT,
SB_MESSAGE.M_START_TIME,
SB_BATCH.B_CREATE_DT - CAST(SB_MESSAGE.M_START_TIME AS TIMESTAMP) AS diff
FROM SB_BATCH
INNER JOIN SB_MESSAGE
ON SB_BATCH.B_UID = SB_MESSAGE.M_B_UID
) t
Convert the timestamp to a date using cast(... as date). Then take the difference between the dates, which is a number - expressed in days, so if you want it in minutes, multiply by 24*60. Then round the result as needed. I made up a small example below to isolate just the steps needed to answer your question. (Note that your query has many other problems, for example you didn't actually take a difference of anything anywhere. If you need help with your query in general, please post it as a separate question.)
select ts, dt, round( (sysdate - cast(ts as date))*24*60, 2) as time_diff_in_minutes
from (select to_timestamp('2016-08-23 03:22:44.734000', 'yyyy-mm-dd hh24:mi:ss.ff') as ts,
sysdate as dt from dual )
;
TS DT TIME_DIFF_IN_MINUTES
-------------------------------- ------------------- --------------------
2016-08-23 03:22:44.734000000 2016-08-23 08:09:15 286.52
WHERE (ResTRRequest.RequestTime BETWEEN TO_CHAR(TRUNC(TO_DATE('2012-12-01 20:10:10', 'HH')), 'YYYY-MM-DD HH24:MI:SS')
AND TO_CHAR(TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '59:59' MINUTE TO SECOND, 'YYYY-MM-DD HH24:MI:SS'))
I have above where condition in query when i execute it,it gives me hours must be between 1 to 12 due to static date I have given i.e ''2012-12-01 20:10:10', 'HH')' if I put sysdate the its working fine but due to static date it gives me error.
Let's break this down a bit:
WHERE (ResTRRequest.RequestTime
BETWEEN TO_CHAR(TRUNC(TO_DATE('2012-12-01 20:10:10', 'HH')), 'YYYY-MM-DD HH24:MI:SS')
AND TO_CHAR(TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '59:59' MINUTE TO SECOND, 'YYYY-MM-DD HH24:MI:SS'))
In the first place, I don't think you mean this: TRUNC(TO_DATE('2012-12-01 20:10:10', 'HH')), I think maybe you mean this: TRUNC(TO_DATE('2012-12-01 20:10:10'), 'HH'). The number from 1-12 error comes from the fact that you have an hour of 20 and are trying to convert it into a date with the mask of HH. But as I said I think that's a typo. You can also use a TIMESTAMP literal here rather than TO_DATE():
TRUNC(TIMESTAMP'2012-12-01 20:10:10', 'HH')
Second, and just to get this out of the way, are you storing dates or timestamps as strings? That's not a good idea.
Third, it's not a good idea to use BETWEEN in date comparisons because you can miss the edge cases. It might be better to rewrite this as follows:
WHERE ( ResTRRequest.RequestTime >= TO_CHAR(TRUNC(TO_DATE('2012-12-01 20:10:10'), 'HH'), 'YYYY-MM-DD HH24:MI:SS')
AND ResTRRequest.RequestTime < TO_CHAR(TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '1' HOUR, 'YYYY-MM-DD HH24:MI:SS') )
Problem is in mask:
TO_DATE('2012-12-01 20:10:10', 'HH')
Replace with this one:
TO_DATE('2012-12-01 20:10:10', 'HH24')
Assuming that ResTRRequest.RequestTime is of a date type, this Where clause will work:
where ResTRRequest.RequestTime
BETWEEN TRUNC(TO_DATE('2015-02-26 20:10:10', 'YYYY-MM-DD HH24:MI:SS'), 'HH')
AND TRUNC(CURRENT_TIMESTAMP, 'HH') + INTERVAL '59:59' MINUTE TO SECOND
If you have to compare character representations, keep in mind that you compare in lexicographic order, meaning that prefixes of strings are sorted before their strings! Avoid ensueing complications by using identical formatting models with componnents arranged in the order of decreasing significance. E.g.
TO_CHAR(<whatever>, 'YYYY-MM-DD HH24:MI:SS')
but not
TO_CHAR(<whatever>, 'MM/DD/YYYY HH24:MI:SS')
If the language setting on Oracle is set for using the 12 hours time, this problem will occur when converting the 24 hours time format.
There are two solutions to this :
Convert TIMESTAMP/DATE format in Oracle client
alter session set nls_timestamp_format='YYYY-MM-DD HH24:MI:SS.FF6';
Convert query to match 24hr format
SELECT * FROM TEST_ WHERE DOB > TRUNC(TIMESTAMP'1970-01-01 20:10:10', 'HH');
or
SELECT * FROM TEST_ WHERE DOB > to_date('1970-01-01 20:00:00','YYYY-MM-DD HH24:MI:SS');
One more thing to watch out for in the case you get this error is the data itself.
I've had date stored in xml tag that I had to parse and convert with TO_DATE with this format specifier 'MM/dd/YYYY HH:MI:SS AM'. SQL broke with "ORA-01849: hour must be between 1 and 12" because some records were written like this: "12/20/2017 16:45:00 PM". Pay attention to 16h and PM specfier...
I need to add 30 minutes to values in a Oracle date column. I do this in my SELECT statement by specifying
to_char(date_and_time + (.000694 * 31)
which works fine most of the time. But not when the time is on the AM/PM border. For example, adding 30 minutes to 12:30 [which is PM] returns 1:00 which is AM. The answer I expect is 13:00. What's the correct way to do this?
In addition to being able to add a number of days to a date, you can use interval data types assuming you are on Oracle 9i or later, which can be somewhat easier to read,
SQL> ed
Wrote file afiedt.buf
SELECT sysdate, sysdate + interval '30' minute FROM dual
SQL> /
SYSDATE SYSDATE+INTERVAL'30'
-------------------- --------------------
02-NOV-2008 16:21:40 02-NOV-2008 16:51:40
All of the other answers are basically right but I don't think anyone's directly answered your original question.
Assuming that "date_and_time" in your example is a column with type DATE or TIMESTAMP, I think you just need to change this:
to_char(date_and_time + (.000694 * 31))
to this:
to_char(date_and_time + (.000694 * 31), 'DD-MON-YYYY HH24:MI')
It sounds like your default date format uses the "HH" code for the hour, not "HH24".
Also, I think your constant term is both confusing and imprecise. I guess what you did is calculate that (.000694) is about the value of a minute, and you are multiplying it by the number of minutes you want to add (31 in the example, although you said 30 in the text).
I would also start with a day and divide it into the units you want within your code. In this case, (1/48) would be 30 minutes; or if you wanted to break it up for clarity, you could write ( (1/24) * (1/2) ).
This would avoid rounding errors (except for those inherent in floating point which should be meaningless here) and is clearer, at least to me.
UPDATE "TABLE"
SET DATE_FIELD = CURRENT_TIMESTAMP + interval '48' minute
WHERE (...)
Where interval is one of
YEAR
MONTH
DAY
HOUR
MINUTE
SECOND
from http://www.orafaq.com/faq/how_does_one_add_a_day_hour_minute_second_to_a_date_value
The SYSDATE pseudo-column shows the current system date and time. Adding 1 to SYSDATE will advance the date by 1 day. Use fractions to add hours, minutes or seconds to the date
SQL> select sysdate, sysdate+1/24, sysdate +1/1440, sysdate + 1/86400 from dual;
SYSDATE SYSDATE+1/24 SYSDATE+1/1440 SYSDATE+1/86400
-------------------- -------------------- -------------------- --------------------
03-Jul-2002 08:32:12 03-Jul-2002 09:32:12 03-Jul-2002 08:33:12 03-Jul-2002 08:32:13
I prefer using an interval literal for this, because interval '30' minute or interval '5' second is a lot easier to read then 30 / (24 * 60) or 5 / (24 * 60 * 69)
e.g.
some_date + interval '2' hour
some_date + interval '30' minute
some_date + interval '5' second
some_date + interval '2' day
You can also combine several units into one expression:
some_date + interval '2 3:06' day to minute
Adds 2 days, 3 hours and 6 minutes to the date value
The above is also standard SQL and also works in several other DBMS.
More details in the manual: https://docs.oracle.com/database/121/SQLRF/sql_elements003.htm#SQLRF00221
If the data type of the field is date or timestamp, Oracle should always give the correct result if you add the correct number given in number of days (or a the correct fraction of a day in your case). So if you are trying to bump the value in 30 minutes, you should use :
select field + 0.5/24 from table;
Based on the information you provided, I believe this is what you tried to do and I am quite sure it works.
Can we not use this
SELECT date_and_time + INTERVAL '20:00' MINUTE TO SECOND FROM dual;
I am new to this domain.
like that very easily
i added 10 minutes to system date and always in preference use the Db server functions not custom one .
select to_char(sysdate + NUMTODSINTERVAL(10,'MINUTE'),'DD/MM/YYYY HH24:MI:SS') from dual;
Be sure that Oracle understands that the starting time is PM, and to specify the HH24 format mask for the final output.
SELECT to_char((to_date('12:40 PM', 'HH:MI AM') + (1/24/60) * 30), 'HH24:MI') as time
FROM dual
TIME
---------
13:10
Note: the 'AM' in the HH:MI is just the placeholder for the AM/PM meridian indicator. Could be also 'PM'
Oracle now has new built in functions to do this:
select systimestamp START_TIME, systimestamp + NUMTODSINTERVAL(30, 'minute') end_time from dual
Based on what you're asking for, you want the HH24:MI format for to_char.
To edit Date in oracle you can try
select to_char(<columnName> + 5 / 24 + 30 / (24 * 60),
'DD/MM/RRRR hh:mi AM') AS <logicalName> from <tableName>
SELECT to_char(sysdate + (1/24/60) * 30, 'dd/mm/yy HH24:MI am') from dual;
simply you can use this with various date format....