How to query for time delta in minutes? - sql

I'm trying to get the time delta in minutes between two times. The query returned incorrect time deltas:
time_delta should be 133 and 90 respectively.
SELECT arrival_time, discharge_time
,STRFTIME("%H%M", discharge_time)-STRFTIME("%H%M", arrival_time) AS time_delta
FROM table;

Your query does not work because it converts the dates to string representations (in format %H%M), then it tries to substract the two strings - which does not do what you expect.
You can, instead, convert the dates to unix epochs, so you get a time difference in seconds :
select arrival_time, discharge_time,
unixepoch(discharge_time) - unixepoch(arrival_time) as time_delta_in_seconds
from mytable;
unixepoch() is a syntax shortcut for strftime('%s', ...), as explained in the SQLite documentation.

Related

Difference between 2 timestamps in Oracle SQL

Please help in finding the difference between 2 timestamps in SQL
I tried using
Select (cast(sysdate as timestamp) - cast(sysdate-2 as timestamp)) diff from dual;
I got 'ORA-00911:invalid character' error
If you want something that looks a bit simpler, try this for finding events in a table which occurred in the past 1 minute:
With this entry you can fiddle with the decimal values till you get the minute value that you want. The value .0007 happens to be 1 minute as far as the sysdate significant digits are concerned. You can use multiples of that to get any other value that you want:
select (sysdate - (sysdate - .0007)) * 1440 from dual;
Result is 1 (minute)
Then it is a simple matter to check for
select * from my_table where (sysdate - transdate) < .00071;
You are not finding the difference between two timestamps; you are finding the difference between two dates and casting them to timestamps in the process. This is unnecessary and you can just leave them as date values and explicitly cast the difference to an INTERVAL DAY TO SECOND data type (which would be the output if you used timestamps):
SELECT (SYSDATE - (SYSDATE - 2)) DAY TO SECOND AS diff
FROM DUAL;
Which outputs the interval:
DIFF
+02 00:00:00.000000
However, your code works db<>fiddle.
You will probably find that the error:
ORA-00911:invalid character
Is nothing to do with your query and is related to the ; statement terminator at the end. If you are running your query through a 3rd-party application (i.e. C#, Java, Python, etc.) then they will pass single statements to the database to execute and, in this case, having the statement terminator is invalid syntax (as there will only be one SQL statement) and you just need to remove it.

time difference in sql Oracle

I need to know a difference between start time and end time. Both are DATETIME fields, I tried to use "-" and DATADIFF.
I already tried using DATADIFF and simple subtraction converting the field to just time.
(to_date(Fim_Hora,'HH24:MI') - to_date(Inicio_Hora,'HH24:MI')) AS Diferenca
DATADIFF(MIN,Fim_Hora,Inicio_Hora)
I need to know the time in minutes for use as parameters.
Oracle does not have a time data type. Usually, subtraction works well enough:
select (end_time - start_time) as diff
You may need to convert to a string if you want it formatted in a particular way.
In Oracle, you can directly substract dates, it returns the difference between the dates in days. To get the difference in minutes, you can multiply the result by 24 (hours per days) and 60 (minutes per hour):
(Fim_Hora - Inicio_Hora) * 24 * 60 diff_minutes
This assumes that both Fim_Hora and Inicio_Hora are of datatype DATE.

How to subtract hours and minutes from each other in PostgreSQL

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)

Cast integer with hour to time in PostgreSQL

I have a number passed as integer and would like to convert it to time, and use this number as hour.
I have found solutions for using a number as minutes, but I'm not familiar with PostgreSQL syntax. Not sure what to do here:
select CAST(to_char(czas, 'FM99909:99') AS TIME WITHOUT
TIME ZONE)::TIME from test
The result would be:
00:15:00
But I'm looking for a way to make it:
15:00:00
I have been working with MS SQL for quite a while, I'm surprised how much more complex PostgreSQL syntax is.
If your column test.czas to signifies hours just multiply with interval '1 hour':
SELECT (interval '01:00' * czas)::time FROM test;
Produces your desired result exactly, even with fractional digits.
'01:00' and '1 hour' are equivalent interval literals.
For czas > 24 you get the remainder (full days cut off) - like if you'd use czas%24.
Related:
Postgres data type cast
How do I add a column to a date in Postgres?

SQL to extract matlab date from postgres db

I'd like to construct a query to "convert" a postgresql datetime to a matlab datenum. Experience with other DBs has shown me that converting the date on the DB side is much faster than doing it in matlab.
Matlab stores dates as number of days (including fractions) since an arbitrary epoch of a gregorian, non-existent date of 00-00-0000.
On Oracle, it's simple, because Oracle stores dates internally like matlab does, but with a different epoch.
select (date_column_name - to_date('01-Jan-0001') + 365) ...
A straightforward conversion of this to PG syntax doesn't work:
select (date_column_name - date '01-Jan-0001' + interval 365) ...
I've started with a particular day in matlab, for testing:
>> num2str(datenum('2010-10-02 12:00'))
ans =
734413.5
I've been in and out of the pg docs all day, extracting epochs and seconds, etc. And I've gotten close. Basically this gets the seconds in an interval, which I just divide by the seconds in a day:
Select cast(extract(epoch from (timestamp '2010-10-02 12:00'
- timestamp '0000-01-01 23:10'
+ interval '2 day'
)
) as real
)/(3600.0*24.0) AS MDate
answer:
734413.51111111111
But that exhibits some bizarre behavior. Adjusting the minutes from the epoch timestamp doesn't change the answer, except at one particular minute - i.e 23:09 is one answer, 23:10 is another, and it stays the same from 23:10 to 23:59. (other hours have similar behavior, though the particular "minute" is different.)
Any ideas? Maybe on another way to do this?
edit:
using 8.4.2
Well, extract(epoch from t::timestamp) will give seconds since the UNIX epoch (01 Jan 1970), and produces 1286017200 for '2010-10-02 12:00:00'.
Matlab gives 734413.5 for the same timepoint, but that's in days- so 63453326400 seconds, an offset of 62167309200.
So to convert postgres epoch time to matlab datenum, we should be able to just add that offset and convert back to days.
steve=# select (extract(epoch from '2010-10-02 12:00:00'::timestamp) + 62167309200) / (24*3600);
?column?
----------
734413.5
(1 row)
It seems that the cast was the problem.
Select extract(epoch from (timestamp '2010-10-02 12:00:01'
- timestamp '0000-01-01 00:00'
+ interval '1 day'))/(3600.0*24.0)
works like a champ.