Show time diff as HH:MM:SS between two datetimes in SQLite - sqlite

I got two different datetimes: 2020-05-18 12:30:01 and 2020-05-17 13:00:00.
I want to show the time difference between them in the format HH:MM:SS, which is 23:30:01.
If the difference is higher than 24 hours, let's say 28 hours, 12 minutes and 45 seconds, it would show like 28:12:45.
How can I do that in SQLite?

SQLite supports a limited number of functions for datetime manipulation.
One of these functions is strftime(), and
strftime('%s', somedate)
returns the number of seconds from '1970-01-01' up to somedate.
With the use of this function, arithmetic calculations, string padding and concatenations you can get what you want like this:
CASE WHEN ((strftime('%s', date1) - strftime('%s', date2)) / 3600) < 10 THEN '0' ELSE '' END ||
((strftime('%s', date1) - strftime('%s', date2)) / 3600) || ':' ||
SUBSTR('0' || (((strftime('%s', date1) - strftime('%s', date2)) / 60) % 60), -2) || ':' ||
SUBSTR('0' || ((strftime('%s', date1) - strftime('%s', date2)) % 60), -2)
Replace date1 and date2 with your dates.
See a simplified demo.

SELECT time(
(
julianday('2020-05-18 12:30:01')-
julianday('2020-05-17 13:00:00')
)*60*60*24, 'unixepoch'
);
answsers the question when time difference is lower than 24h...

Related

Sqlite sum time

I have a table with a column that contained time duration of events.
It it formatted as 'h:mm:ss'
I found the function strftime - but according to the manual, it requires the format 'hh:mm:ss'
can someone tell me how i can sum up the duration without recreating the sql table?
Is this what you want ?
with t as (
select '4:02:01' as v
union all
select '9:30:12'
union all
select '2:14:00'
),
diff as (
select sum(strftime('%s', '0'||v) - strftime('%s', '00:00:00')) as v
from t
)
select (v/3600) || ' hours, ' || (v%3600/60) ||' minutes, '
|| (v%60) || ' seconds.'
from diff
https://www.db-fiddle.com/f/2SNbFYQv2zYiCE4gw5bhzi/0
You can use time() and strftime():
select
time(sum(
strftime('%s', case length(timecolumn) when 7 then '0' else '' end || timecolumn)
- strftime('%s','00:00:00')),
'unixepoch') totaltime
from tablename
The result time sum will be in format hh:mm:ss.

How to calculate previous month data on starting of next month in Teradata

I am using condition below to show data for current month only/previous month(if its new month started).
let's say today is 3rd june so it should only give 1st an 2nd data,if its 10 it should give data from 1 to 9th,similarly it should be like this until month end but when there will be 1st of next month it should give data from previous month. the conditions I am using are giving blank data on every 1st. . Here is the condition I am using:
where Datestarted between CURRENT_DATE - EXTRACT( DAY FROM CURRENT_DATE) + 1
AND
ADD_MONTHS(( CURRENT_DATE - EXTRACT (DAY FROM CURRENT_DATE) + 1), 1) - 1
You probably need to base your calculation on yesterday, not today:
where Datestarted between (CURRENT_DATE-1) - EXTRACT( DAY FROM CURRENT_DATE-1) + 1
AND
CURRENT_DATE-1
Do you maybe mean previous month to date?
Try this:
select
calendar_date
from
sys_calendar.calendar
where
calendar_date between cast((ADD_MONTHS(CURRENT_DATE,-1)/100*100)+1 as DATE) and
add_months(current_date,-1)-1
EDIT: Based on your comments, let's try this:
SELECT
calendar_date
FROM
sys_calendar.CALENDAR
WHERE
(EXTRACT(DAY FROM CURRENT_DATE) = 1 --previous month
AND
Calendar_Date BETWEEN CAST((ADD_MONTHS(CURRENT_DATE, - 1)/100 * 100) + 1 AS DATE)
AND CURRENT_DATE - EXTRACT(DAY FROM CURRENT_DATE))
OR--current mtd
(
Calendar_Date BETWEEN CAST((CURRENT_DATE / 100 * 100) + 1 AS DATE)
AND CURRENT_DATE - 1
)
ORDER BY calendar_date

sqlite - making TIMEDIFF as in MySQL

I want to make a function call that hase efect in SQLite like TIMEDIFF in MySQL.
I made this:
select strftime('%s','2012-01-01 12:00:00') - strftime('%s','2004-01-01 02:34:56')
but this is just the number of seconds. So how can i make a str like %Y-%m-%d %H:%M:%S where %H:%M:%S is the hours, minutes and seconds difference, and when it is bigger then 24 hours then %d will show how much dais it is and so on with %Y and %m.
You cannot represent a time difference with %Y-%m-%d ..., at least not as a date format. How would you express less than a day of difference? (0000-00-00 ... is not a valid date). Also, what would a month be? 30 days? 31 days? 23423432 days?
I suggest you keep your difference in seconds, and when presenting it you adapt it as necessary.
On the other hand, if you really want to do as you asked, here's one way:
sqlite> select datetime(strftime('%s','2012-01-01 12:00:00')
- strftime('%s','2004-01-01 02:34:56') - 62167305600, 'unixepoch');
0007-12-31 09:25:04
Even if I feel the downvote by the OP wasn't justified, I can't stop myself from explaining why what I mentioned above as clearly not a very good option returns "incorrect" results when the time difference is less than 1 day: the reason is implied in what I wrote above: there is no such date as 0000-00-00 ... so instead the datetime returned goes in negative territory: -001-12-31 ...
Here's a way to obtain 438:53:45, but it's quite involved:
earlier date: d1
later date: d2
select
cast(
(strftime('%s', d2) - strftime('%s', d1)) / 86400 * 24
+ cast(strftime("%H", time(strftime('%s', d2)
- strftime('%s', d1), 'unixepoch'))
as int)
as text)
|| ":"
|| substr(time(strftime('%s', d2) - strftime('%s', d1), 'unixepoch'), 4);
Example:
d1 = '2004-01-01 02:34:56'
d2 = '2012-01-01 12:00:00'
sqlite> select cast((strftime('%s','2012-01-01 12:00:00') - strftime('%s','2004-01-01 02:34:56')) / 86400 *24 + cast(strftime("%H", time(strftime('%s','2012-01-01 12:00:00') - strftime('%s','2004-01-01 02:34:56'), 'unixepoch')) as int) as text)
|| ":"
|| substr(time(strftime('%s','2012-01-01 12:00:00') - strftime('%s','2004-01-01 02:34:56'), 'unixepoch'), 4);
70137:25:04

SQLite: express the difference as days, hours, minutes between two given dates

I am trying to express the difference of two given dates in days, hours, and minutes (like 1 day, 6 hours, 17 minutes.) as SQLite query output. I have entryin and entryout as datetime fields in a SQLitedatabase. I tried all combinations of julianday and strftime but still running into rough weather.
I tried strftime('%d %H:%M', julianday(entryout)-julianday(entryin)). For a row the values are 2011-11-10 11:46, and 2011-11-09 09:00. but the output is 25 14:46 instead of 01 02:46.
Can some one help me with this, or point me correct logic for this? Thanks in advance.
You can try something like this:
SELECT
CAST((strftime('%s', '2011-11-10 11:46') - strftime('%s', '2011-11-09 09:00')) / (60 * 60 * 24) AS TEXT) || ' ' ||
CAST(((strftime('%s', '2011-11-10 11:46') - strftime('%s', '2011-11-09 09:00')) % (60 * 60 * 24)) / (60 * 60) AS TEXT) || ':' ||
CAST((((strftime('%s', '2011-11-10 11:46') - strftime('%s', '2011-11-09 09:00')) % (60 * 60 * 24)) % (60 * 60)) / 60 AS TEXT);

Can you format 24-hour time string into 12-hour time string with AM/PM?

I store some time values in sqlite in %H:%M string format (for example "15:43"), but I would like to get them out formatted in 12 hour format with AM/PM indicators (for example "3:43 PM"). Is this possible with sqlite (and if so, how), or do I need to do this in my application code?
Unless you extend sqlite with your own custom function, you'll have to do this is code.
sqlite's strftime date formatting function only supports a small subset of its C counterpart, insufficient for your problem. sqlite also lacks a selection construct like IF or CASE, making simple if/else impossible.
Some pseudo code to help you on the way:
if (hourpart of time >= 12)
subtract 12 from hours
append string " pm"
else // hourpart < 12
append string " am"
end if
In SQL you can accomplish this using the CASE syntax.
After taking a closer look at the problem:
SELECT (CASE HOUR(myTimeColumn) >= 12 WHEN 1 THEN
((HOUR(myTimeColumn) - 12) + '-' + MINUTE(myTimeColumn) + ' pm')
ELSE
(HOUR(myTimeColumn) + '-' + MINUTE(myTimeColumn) + ' am')
AS AmPmTime,
someOtherColumn
FROM myTable
I'm not entirely sure that all of that is valid SQLite syntax, but you should be able to correct the bugs.
There are a few special situation that are covered here. I'm using 'now' as a source, but you can adjust it for your string:
select
CASE
--For 00:05, for example.
WHEN (strftime('%H', 'now', 'localtime') - 12) = -12
THEN '12:' || strftime('%M', 'now', 'localtime') ||' '|| 'AM'
--For 12:05, for example.
WHEN (strftime('%H', 'now', 'localtime') - 12) = 0
THEN '12:' || strftime('%M', 'now', 'localtime') ||' '|| 'PM'
--other am time
WHEN (strftime('%H', 'now', 'localtime') - 12) < 0
THEN strftime('%H', 'now', 'localtime') ||':'||
strftime('%M', 'now', 'localtime') ||' '|| 'AM'
ELSE
--other pm time
(cast(strftime('%H', 'now', 'localtime') as integer) - 12) ||':'||
strftime('%M', 'now', 'localtime') ||' '|| 'PM'
END here_you_go_usa;
Do it in your application. Store it in normal 24h format in the database. In the database it can be stored as a Date entry instead of a string (correct me if im wrong)
As PoweRoy recomended, this belongs in the application.
It is recommended that any kind of data stored of used in communication uses a standard, locale-insensitive format: http://www.mihai-nita.net/article.php?artID=20051025a
Here's a working one.. Thanks to Tomas
SELECT
PatientName,
CASE WHEN
StrFTime('%H', AppointmentTime) % 12 = 0 THEN 12
ELSE StrFTime('%H', AppointmentTime) % 12 END
|| ':' ||
StrFTime('%M', AppointmentTime)
|| ' ' ||
CASE WHEN
StrFTime('%H', AppointmentTime) > 12 THEN 'PM'
ELSE 'AM' END
`APP_TIME`
From Patients;
OUTPUT
Abdul Salim, 12:05 PM

Resources