This question already has answers here:
Convert from date to epoch-Oracle
(3 answers)
PL/SQL sysdate to Unix epoch time in ms
(1 answer)
Closed 3 years ago.
I need to convert an Oracle DATE value to a Unix style seconds-since-epoch-start value.
I've tried various combinations of Oracle's conversions such as:
select to_number(to_date('10/05/2019','mm/dd/yyyy')) from dual;
select to_number(to_timestamp(to_date('10/05/2019','mm/dd/yyyy'))) from dual;
select to_number(to_char(to_date('10/05/2019','mm/dd/yyyy'))) from dual;
Nothing seems to work. Does anyone have an answer to this?
If that's number of seconds since Jan 01 1906, then:
SQL> select sysdate - date '1906-01-01' days,
2 (sysdate - date '1906-01-01') * 24 * 60 * 60 unix_style
3 from dual;
DAYS UNIX_STYLE
---------- ----------
41555,811 3590422068
SQL>
Why? Because - when you subtract two dates in Oracle, result is number of days. Then you have to multiply it by 24 (as there are 24 hours in a day), by 60 (as there are 60 minutes in an hour) and once again by 60 (as there are 60 seconds in a minute).
Of course, you could have multiplied it by 86400 (which is 24 * 60 * 60), but - former is difficult to understand while latter shows what's going on and why.
If - as Wernfried commented - date differs from the one you said, you'd just replace date '1906-01-01' with date '1970-01-01'.
Related
This question already has answers here:
Calculating difference between two timestamps in Oracle in milliseconds
(11 answers)
Calculate difference between 2 date / times in Oracle SQL
(21 answers)
Closed 3 years ago.
TIMESTAMPDIFF(HOUR, pk.consprtydate, rs.consprtydate)
wanted the difference of hours from two dates and extract the hours in oracle sql
In oracle, you can easily achieve it by substracting two date fields as following:
Date2 - Date1 -- returns number of days between dates
(Date2 - Date1)/24 -- returns number of days between dates
MONTHS_BETWEEN(Date1, Date2) -- returns number of months between dates
Cheers!!
It depends on the datatype. IF they are of Oracle type TIMESTAMP, then follow the methods already answered here
If they are of type date, then - as said by Tejash- simple subtraction gives the difference in days that you would then need to round to hours. (integer portion will be days = 24 hours, and the decimal portion will be in fractions of a day)
e.g.) to round down to the integer number of hours without a fractional part:
(days * 24 hours, plus the fraction of a day * 86400 seconds in a day / 3600 seconds in an hour)
SELECT trunc(date1 - date2) * 24 + trunc((mod (date1-date2,1) * 86400) / 3600)
FROM DUAL
I have two fields dateTS and closingTime.
dateTS is a normal timestamp field (e.g. 2019-07-13 22:31:10.000000)
closingTime is a HH:MM format of when a store closes (e.g. 23:00)
I need a PostgreSQL query to subtract the two field and get the number of minutes difference between them.
Using the examples given above the difference between the two fields would be 28 minutes
So far I've tried different variations of the datediff function, but it won't work.
My guess is I either have to
a. generate a fake timestamp for closingTime which is the same day as the dateTs field and subtract the 2 timestamps.
or
b. convert the hour/minutes of both field to a float and subtract the two values to get the hours difference and convert that to minutes
You can just subtract them by converting the timestamp to a time:
select closingtime - datets::time
from your_table;
That will give you an interval as the result.
To convert that to minutes you can get the number of seconds and divide it by 60:
select (extract epoch from closingtime - datets::time) / 60
from your_table;
Cast your closing time to an interval and the timestamp to time and then subtract the two. By casting the timestamp to time you are effectively discarding the date part. You can the subtract one from the other to generate the difference as an interval.
select closingTime::interval - dateTS::time...
e.g.:
# select '23:00'::interval - now()::time;
?column?
-----------------
05:31:00.031141
(1 row)
If needed you can then convert the interval to minutes:
# select extract(epoch from ('23:00'::interval - now()::time)) / 60;
?column?
------------------
327.435313083333
(1 row)
How can i subtract days to a timestamp in CrateDB SQL query?
Exist something similar to this?
TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 14 DAY)
Don't think there is a built in function but you could do something like this
SELECT DATE_FORMAT(CURRENT_TIMESTAMP - 1000*60*60*24*14) LIMIT 100
in this example (1000 * 60 * 60) * 24 * 14 (24 is to get days and 14 is your number of days)
NB. You can also cast dates into timestamp and perform similar functionality
SELECT ABS(cast('2019-01-1' AS TIMESTAMP) - CURRENT_TIMESTAMP ) / (1000*60*60*24) LIMIT 100
this will get you a number of days between now and 1st of January
So far that's all what they have in their docs
You can subtract INTERVAL from TIMESTAMP, but before any matematichal operation you need to CAST the datatype, you can do it in this way:
SELECT now() - CAST('14 day' AS INTERVAL)
Or the same function of above, but in a contracted way
SELECT now() - '14 day'::INTERVAL;
As a string to be CAST to an INTERVAL you can use a number followed by any of this:
second
minute
hour
day
week
month
quarter
year
This question already has answers here:
How to find difference b/w TIMESTAMP format values in Oracle?
(3 answers)
Closed 8 years ago.
So I'm trying to convet a timestamp to seconds.
I read that you could do it this way
to_char(to_date(10000,'sssss'),'hh24:mi:ss')
But turns out this way you can't go over 86399 seconds.
This is my date format: +000000000 00:00:00.000000
What's the best approach to converting this to seconds? (this is the result of subtracting two dates to find the difference).
You could convert timestamp to date by adding a number (zero in our case).
Oracle downgrade then the type from timestamp to date
ex:
select systimestamp+0 as sysdate_ from dual
and the difference in secondes between 2 timestamp:
SQL> select 24*60*60*
((SYSTIMESTAMP+0)
-(TO_TIMESTAMP('16-MAY-1414:10:10.123000','DD-MON-RRHH24:MI:SS.FF')+0)
)
diff_ss from dual;
DIFF_SS
----------
15140
It looks like you're trying to find the total number of seconds in an interval (which is the datatype returned when you subtract two timestamps). In order to convert the interval to seconds, you need to extract each component and convert them to seconds. Here's an example:
SELECT interval_value,
(EXTRACT (DAY FROM interval_value) * 24 * 60 * 60)
+ (EXTRACT (HOUR FROM interval_value) * 60 * 60)
+ (EXTRACT (MINUTE FROM interval_value) * 60)
+ EXTRACT (SECOND FROM interval_value)
AS interval_in_sec
FROM (SELECT SYSTIMESTAMP - TRUNC (SYSTIMESTAMP - 1) AS interval_value
FROM DUAL)
If you want the number of seconds between two dates (or timestamps),
select floor(
(to_date(to_char(timestamp1, 'yyyy-mm-dd HH24:MI:ss'),'yyyy-mm-dd HH24:MI:ss')
- to_date(to_char(timestamp2, 'yyyy-mm-dd HH24:MI:ss'),'yyyy-mm-dd HH24:MI:ss')
)
* 24 -- hours per day
* 60 -- minutes per hour
* 60 -- seconds per minute
)
etc
I thought it was really simple but it isn't.
SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY')
- 1/(24*50*60*1000) data
FROM dual;
It simply doesn't work.
Other details:
SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY') -
NUMTODSINTERVAL(1/(24*50*60*1000),'HOUR') data
FROM dual;
doesn't work..
The right seems to be
SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY') -
NUMTODSINTERVAL(1/(24*25*60*1000),'HOUR') data
FROM dual;
Why? How does it work?
For adding or subtracting an amount of time expressed as a literal you can use INTERVAL.
SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY')
- INTERVAL '0.001' SECOND
FROM dual;
As well there are now standard ways to express date and time literals and avoid the use of various database specific conversion functions.
SELECT TIMESTAMP '2012-10-08 00:00:00'
- INTERVAL '0.001' SECOND DATA
FROM dual;
For your original question the time part of a day is stored in fractional days. So one second is:
1 / (hours in day * minutes in hour * seconds in a minute)
Divide by 1000 to get milliseconds.
1 / (24 * 60 * 60 * 1000)
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.
The answer posted above subtracts a tenth of a millisecond from the date. I think what you want is the following:
SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY')-NUMTODSINTERVAL(1/1000,'SECOND')
FROM dual;
Output:
DATA
---------------------------------------------------------------------------
09-AUG-12 11.59.59.999000000 PM
^^^
|||
tenths|thousandths
|
hundredths
The following NUMTODSINTERVAL(1/(24*25*60*1000),'HOUR') seems to work only because 24*25 = 600. But that number is wrong because 1/(600*60*1000) of an hour is a tenth of a millisecond, not a millisecond. If you want to use 'HOUR' in NUMTODSINTERVAL() you should use 1/(60*60*1000) (sixty minutes in an hour, sixty seconds in a minute, 1000 ms in a second).
This is correct (with a millisecond being 1000th of a second):-
SELECT TO_TIMESTAMP('10/08/2012','DD/MM/YYYY') - NUMTODSINTERVAL(1/1000,'SECOND') data FROM dual;
DATA
-----------------------------
09-AUG-12 23.59.59.999000000
As to why the other code isn't working it's because you aren't calculating a millisecond correctly. An hour must be divided by 60 to give minutes and again by 60 to given seconds then by 1000 to give a millisecond, thus if you must use HOUR as the interval then it is:-
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
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