简体   繁体   中英

Casting a specific hour and minute and getting the time difference

I have the following:

trunc(sysdate - to_timestamp(trunc(sysdate, 'YYYY-MM-DD') || ' 12:30', 'YYYY-MM-DD HH245:MI')  * 1440,1)

What I'm trying to do is, using the date portion of sysdate and casting 12:30 to the time part. Then calculating the difference between sysdate@12:30 and the current sysdate.

I'm getting:

ORA-00932: inconsistent datatypes: expected NUMBER got TIMESTAMP

after the minus sign.

Any ideas?

You're getting that error because you're trying to multiply a timestamp by 1440, rather than the difference between the date and timestamp - multiplication has higher precedence than subtraction . You also have HH245 instead of HH24 in your format model; trunc(sysdate, 'YYYY-MM-DD') will throw "ORA-01898: too many precision specifiers"; and if you changed that to to_char(sysdate, 'YYYY-MM-DD') || ... to_char(sysdate, 'YYYY-MM-DD') || ... you would be subtracting a timestamp from a date which gives you an interval , not a number, and would throw a different ORA-00932 error.

Fixing all of those issues, you would end up with:

trunc((sysdate - to_date(to_char(sysdate, 'YYYY-MM-DD') || ' 12:30', 'YYYY-MM-DD HH24:MI')) * 1440, 1)

which would evaluate to 354.2 for me at the moment.

You don't need to convert to or from string though. You can get 12:30 today with:

trunc(sysdate) + (12.5/24)

where trunc(sysdate) gives you midnight today, and 12.5/24 gives you the fraction of a day for 12.5 hours. You can then subtract that from the current time:

sysdate - (trunc(sysdate) + (12.5/24))

to get the difference in days, then multiple that result by 1440 for the number of minutes, and truncate to a single decimal place.

Quick demo with current date and 12:30 today plus the difference three ways:

select sysdate,
  trunc(sysdate) + (12.5/24) as "12:30",
  sysdate - (trunc(sysdate) + (12.5/24)) as diff_days,
  (sysdate - (trunc(sysdate) + (12.5/24))) * 1440 as diff_mins,
  trunc((sysdate - (trunc(sysdate) + (12.5/24))) * 1440, 1) as result
from dual;

SYSDATE             12:30                DIFF_DAYS  DIFF_MINS     RESULT
------------------- ------------------- ---------- ---------- ----------
2019-08-14 18:24:16 2019-08-14 12:30:00 .246018519 354.266667      354.2

As @GordonLinoff hinted, the today-at-12:30 part could be achieved with an interval instead of a fractional day, eg:

trunc(sysdate) + 12.5 * interval '1' hour

or more simply and explicitly:

trunc(sysdate) + interval '12:30' hour to minute

You seem to want your final result as the number of minutes, but you could also get it as an interval, either by converting the current number-of-days intermediate result (or number of minutes) with numtodsinterval() :

numtodsinterval(sysdate - (trunc(sysdate) + interval '12:30' hour to minute), 'DAY')

which is a bit convoluted, or directly:

select systimestamp,
  systimestamp - trunc(sysdate) - interval '12:30' hour to minute as result
from dual;

SYSTIMESTAMP                         RESULT             
------------------------------------ -------------------
2019-08-14 18:24:16.830116000 +01:00 +00 05:54:16.830116

db<>fiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM