Calculating difference between datetime stamp in sqlite - sqlite

I want to calculate the difference between two columns containing datetime stamps in db browser SQLite, I want the answers in minutes, and it keeps returning "Null". Please what could be the reason and how can I solve it?
I tried using this;
SELECT
started_at,
ended_at,
(strftime('%M','ended_at') - strftime('%M','started_at'))as duration
FROM citi1;

You have 'started_at' and 'ended_at' which are string literals and not identifiers and SQLite returns null when you use them in strftime().
But, even if you remove the single quotes you will not get the timestamp difference, because subtracting only the minutes parts of 2 timestamps does not return their difference.
For example, the difference that you would get for started_at = '2022-03-31 13:15:00' and ended_at = '2022-03-31 14:00:00' would be -15 (= 0 - 15).
Use strftime('%s', some_date) which returns the number of seconds since 1970-01-01 00:00:00 for both timestamps, subtract and divide by 60 to get the correct difference in minutes:
SELECT started_at, ended_at,
(strftime('%s', ended_at) - strftime('%s', started_at)) / 60 AS duration
FROM citi1;
See the demo.

Related

SQLite Adding a Calculated Column

I have a table named "Combined_Bike_Ride" with the below sample data in SQLite
started_at
ended_at
27/05/2020 10:03
27/05/2020 10:16
25/05/2020 10:47
25/05/2020 11:05
I want to add a new calculated column "ride_length" where ride_length = (ended_at) - (started_at) in that table.
I used the below sql code but getting a syntax error near AS.
ALTER TABLE Combined_Bike_Ride ADD COLUMN ride_length AS (ended_at) - (started_at)
Am I missing a date calculation? Any help is much appreciated.
First you must change the format of your dates to YYYY-MM-DD hh:mm because this is the only text date format that you can use with SQLite's datetime functions if you want to perform operations such as calculation of time difference.
For this purpose you can use the function strftime().
With strftime('%s', datetimecolumn) you get the number of seconds between 1970-01-01 00:00:00 and the value of datetimecolumn
The correct syntax to add the new column is this:
ALTER TABLE Combined_Bike_Ride
ADD COLUMN ride_length
GENERATED ALWAYS AS ((strftime('%s', ended_at) - strftime('%s', started_at)) / 60)

Negative dates in sqllite database

I am working locally with an sqllite DB. I have imported some records from teradata where there was a date field in the format of 'YYYY-MM-DD'. When i imported the records the date switched from a date to a number. I know this is a feature of sqllite and that one can access it via date(sqllite_date) when selecting it in a where clause.
My problem is that the dates now appear to be a bit odd. For example the year appears to be negative.
Is there anyway to recover this to the correct format?
Below is an example of converting a number in the database into a date
SELECT date(18386)
# -4662-03-28
SELECT datetime('now')
# 2021-02-11 10:41:52
SELECT date(sqllite_date) FROM mydb
# Returns -4662-03-28
# Should return 2020-05-04
I am very new to this area so apologies if this is a basic question. Thank you very much for your time
In SQLite you can store dates as TEXT, REAL or INTEGER.
It seems that you stored the dates in a column with INTEGER or REAL affinity.
In this case, if you use the function date(), it considers a value like 18386 as a Julian day, meaning the number of days since noon in Greenwich on November 24, 4714 B.C.
This is why date(18386) returns 4662-03-28B.C.
But I suspect that the date values that you have are the number of days since '1970-01-01'.
In this case, 18386 days after '1970-01-01' is '2020-05-04'.
So you can get the dates in the format YYYY-MM-DD if you add the value of your column as days to '1970-01-01':
SELECT date('1970-01-01', datecolumn || ' day') FROM tablename
Or by transforming your date values to seconds and treat them as UNIX time (the number of seconds since '1970-01-01 00:00:00 UTC'):
SELECT date(datecolumn * 24 * 3600, 'unixepoch') FROM tablename
Replace datecolumn with the name of your column.

SQLite time difference calculations in HH:MM:SS format

How to calculate time difference in HH:MM:SS format in SQLite?
SELECT time(strftime('%s','2017-11-01 22:25:28') - strftime('%s','2017-11-01'));
gives me:
12:00:00
and
SELECT datetime(strftime('%s','2017-11-01 22:25:28') - strftime('%s','2017-11-01'));
gives me:
-4492-12-04 12:00:00
As documented in the documentation, numbers are interpreted as Julian date numbers by default.
If your value is a number of seconds, you have to interpret it as a number of seconds, i.e., as a Unix timestamp:
SELECT time(strftime('%s','2017-11-01 22:25:28') - strftime('%s','2017-11-01'), 'unixepoch');

sqlite : time difference between two dates in decimals

I have two two timestamp fields (START,END) and a TIME_DIFF field which is of Integer type. I am trying to calculate the time between START and END field.. I created a trigger to do that :
CREATE TRIGGER [TIME_DIFF]
AFTER UPDATE OF [END]
ON [KLOG]
BEGIN
update klog set TIME_DIFF =
cast(
(
strftime('%s',KLOG.END) -
strftime('%s',KLOG.START)
) as INT
) / 60/60;
END
This gives me result in whole hours.Anything between 0 and 59 minutes is neglected.
I am wondering how can I modify this trigger so it displays in decimals?
Meaning, if the time difference is 1 hour 59 minutes the result would display 1.59.If the time difference is 35 minutes it would display 0.35.
To interpret a number of seconds as a timestamp, use the unixepoch modifier. Then you can simply use strftime() to format the value:
strftime('%H:%S',
strftime('%s',KLOG.END) - strftime('%s',KLOG.START),
'unixepoch')
If you use Julian days instead of seconds, you do not need a separate modifier:
strftime('%H:%S',
julianday(KLOG.END) - julianday(KLOG.START))

Date string conversion from R to CSV in Libre Calc

I'm trying to get acquainted with weatherData in R.
Having downloaded a set of temperature data I've then exported it to CSV.
Opening the CSV in Libre Calc shows the date and time for each temperature reading as a string of ten digits. In spite of some Googling I have not found a way of successfully converting the string into the format in which it appears in R.
For example: 1357084200 I believe should translate to 2013-01-01 23:50:00
Any help in getting the correct date in the same date format to appear in Calc via the CSV greatly appreciated.
Here is the direct way:
as.POSIXct(1357084200, origin="1970-01-01", tz="GMT")
#[1] "2013-01-01 23:50:00 GMT"
If it's really a character:
as.POSIXct(as.numeric("1357084200"), origin="1970-01-01", tz="GMT")
I'm not aware of a direct way of doing this, but I believe I've figured out a workaround.
For starters your example is correct. The long number (timestamp) is the number of seconds passed since 1970-01-01 00:00:00. Knowing this you can actually calculate the exact date and time from the timestamp. It's a bit complicated due to needing to take into account the leap years.
What comes in handy is the ability to supply an arbitrary number of days/months/years to LibreOffice function DATE. So in essence you can find out the number of days represented in timestamp by dividing it by 60*60*24 (number of seconds in a minute, number of minutes in an hour, number of hours in a day). And then supply that number to the date function.
timestamp = 1357084200
days = timestamp / FLOOR(timestamp / (60*60*24); 1) // comes out at 15706
actualdate = DATE(1970; 1; 1 + days) // comes out at 2013-01-01
seconds = timestamp - days * 60 * 60 * 24 // comes out at 85800
actualtime = TIME(0; 0; seconds) // comes out at 23:50:00
Then you can concatenate these or whatever else you want to do.

Resources