SQLite difference between dates in millisecond - sqlite

How can I compute in SQLite the minimum interval of time in milliseconds ?
Ok to give some context,
Here is how my table look like:
link_budget table
So there is this time column, I would like to make a request that gives me the intervals between two consecutive rows in milliseconds.
I don't know how to make my requests.
Any suggestions ?

Since SQLite does not have a native datetime data type, instead forcing you to either store as a string or as a number, and you have picked a string, you need to convert it into something that can be calculated upon.
You can use the julianday function for this.
To calculate the difference between two values you would simply do this:
SELECT julianday('2006-07-01 12:08:15.310')-julianday('2006-07-01 12:08:14.141')
This, however, will give you the difference in days. One day contains 86400 seconds and thus 86400000 milliseconds, which gives you this:
SELECT (julianday('2006-07-01 12:08:15.310')-julianday('2006-07-01 12:08:14.141'))*86400000
Note that the precision of the floating point types used internally by SQLite does not have enough precision to get the above value accurate but it should likely be close enough to give you millisecond-precision.
For instance, this:
select (julianday('2006-07-01 12:08:14.141')-julianday('2006-07-01 12:08:14.140'))*(86400000)
Which should give 1 millisecond of difference gives this result:
1.00582838058472

try this:
SELECT (STRFTIME('%s', '2021-10-20 18:22:43') - STRFTIME('%s', '2021-10-20 18:22:42'))*1000;
for timestamps that contain milliseconds try this:
SELECT STRFTIME('%s', '2021-10-20 18:22:43.325')*1000 + SUBSTR(STRFTIME('%f', '2021-10-20 18:22:43.325'), 4) -
( STRFTIME('%s', '2021-10-20 18:22:42.921')*1000 + SUBSTR(STRFTIME('%f', '2021-10-20 18:22:42.921'), 4) );

Related

How to calculate time differences HH:MM in a table?

Im working on a flight-logbook in sqlite.
The "flights"-table has the following structure:
CREATE TABLE flights (event_id INT PRIMARY KEY, date TEXT, offblock TEXT, onblock TEXT, duration TEXT;
My goal is to find a statement that i can insert into the "duration" column, so that I will have the flight duration there.
INSERT INTO flights VALUES (1, "2019-04-04", "12:00", "18:00", XXX);
The result of duration should be 06:00, like this:
SELECT duration from flights WHERE event_id = 1;
06:00
Can anyone give me a working hint how to do this in the easiest possible way?
Thanks a lot!
You can do it with strftime() and time() like this:
SELECT strftime('%H:%M', time(strftime('%s','18:00') - strftime('%s','12:00'), 'unixepoch'))
which results in:
06:00
What you want to do is pretty complex as you have a string which represents time, which there isn't an explicit type for in sqlite. It's quite complicated, but it is possible and you could do the following:
-First remove the colon from the string: how to remove characters from a string in sqlite3 database?
-Then convert this string to an int: Convert string to int inside WHERE clause of SQLITE statment
-You would need to do this for the hours and minutes separately, as ints are obviously 10 based and minutes are 60 based so you can't simply subtract them. You would do this via ths Substr(X,Y,Z) function: https://www.sqlite.org/lang_corefunc.html
-Then you would do arithmetic to subtract final - initial time for both the hours and minutes. https://www.w3resource.com/sqlite/arithmetic-operators.php
-Finally take the calculated hours, and minutes, and add a colon in between them (assuming you want the same format).
Like I said, it's kinda heavy.. but it is doable if this automation saves time in the long run. This should be enough to get you there.

UPDATE an SQLite datetime field with fractional seconds

I'm synchronizing historical data between two systems and I've found a small clock problem between their logs.
I've loaded the data into an SqlLite and need one of the sets by a small amount (~40 milliseconds). However, I'm unable to do so as it seems to always round the time to the nearest second.
For example, attempting something like the following
UPDATE my_table SET my_datetime = DATETIME(my_datetime, '+0.04 seconds') rounds up to the nearest second and I can't find any fractional/millisecond modifier option.
Is there a way to do this that I'm overlooking?
Thanks.
SQLite hasn't a type for datetime. See http://sqlite.org/datatype3.html
Using datetime(...) you are storing your dates as strings. This is equivalent to strftime('%Y-%m-%d %H:%M:%S', ...).
One option is to use a strftime with fractions of seconds:
UPDATE my_table SET my_datetime = STRFTIME('%Y-%m-%d %H:%M:%f',my_datetime, '+0.04 seconds')

In SQLite3, how do I use Datetime('Now') to find datetimes that are more than N days ago?

I have a table that includes a 'LastUpdated' column that is generated when the row is inserted using Sqlite's datetime('now') function.
How do I write a Select statement that finds all rows with 'LastUpdated' more than 100 days old?
I think it's a variant of:
SELECT * FROM Table WHERE (DATETIME('Now')-100 Days) > LastUpdated
But I'm unsure of:
a) How to specify the 100 Days?
b) Whether I can actually compare datetimes like this or if I first have to convert DATETIME('Now') to a string?
c) DATETIME('Now') results in UTC time, correct? I think so from my reading of the documentation, but it was a little confusing...
Figured it out--I didn't see all the handy modifiers at the bottom of the SQLite Datetime Documentation.
A bunch of helpful examples there demonstrating addition/subtraction of any datetime unit (years, months, hours, seconds, etc)
SELECT * FROM Table WHERE (DATETIME('Now','-100 Days') > LastUpdated

Formatting time in SQL as day.hour

I'm creating a report from a stored procedure that pulls two date/times (CreatedDate and ClosedDate). I need a column on the report that shows the difference (i.e. time it took to go from open to close). First, I just subtracted CreatedDate from ClosedDate (in the report [SQL Server Reporting Services], not in the stored procedure) and got a time that looks like this: 72.20:34:18.6230000 (day.hour:minute:second). I need to shrink this down, if possible, to just day.hour...
I was experimenting with some of the functions found on MSDN (http://msdn.microsoft.com/en-us/library/ms186724.aspx). DATEDIFF almost gives me what I need, but I can only specify days or hours, and ideally (as I said), I need it to show the 'time to close' as both (day.hour).
Is this possible?
In SSRS, you can apply a custom format to that column to show only days.hours. Right click the column in design mode -->text box properties-->Number(on left hand side). If you don't see one of the formats for date, time or number that fits what you need, create a custom one at the bottom.
Convert to minutes
divide by 1440 gives whole days
modulo 1440 gives remaining minutes, divide by 60 for hours
Something like (not tested):
SELECT
CAST(DATEDIFF(minute, CreatedDate, ClosedDate) / 1440 AS varchar(20)) + '.'
CAST((DATEDIFF(minute, CreatedDate, ClosedDate) % 1440) / 60 AS varchar(20))
FROM
MyTable
You may need to fiddle with the hours representation in cade I've misunderstood
DATEDIFF for day and hour go by boundaries: that is if there are just 3 minutes between the 2 values spanning midnight, there will be one hour/day difference. So I used minutes
Edit:
To overflow the int from DATEDIFF requires a difference of 4000+ years
Thoughts:
Using datetime2 and have CreatedDate of lowest 0001-01-01
ClosedDate is a sentinel value like 9999-12-31 say for "open" items
CreatedDate and ClosedDate are varchar and conversion to datetime is faulty
Your example shows 72 days difference which would be around 104k minutes.
I would try this to see where you have more than 1000 year differences which would be a mere half billion or so minutes:
SELECT * FROM mytables
WHERE DATEDIFF(year, CreatedDate, ClosedDate) > 1000

Difference between 2 dates in SQLite

How do I get the difference in days between 2 dates in SQLite? I have already tried something like this:
SELECT Date('now') - DateCreated FROM Payment
It returns 0 every time.
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
Difference In Days
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) As Integer)
Difference In Hours
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 As Integer)
Difference In Minutes
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 As Integer)
Difference In Seconds
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 * 60 As Integer)
Both answers provide solutions a bit more complex, as they
need to be. Say the payment was created on January 6, 2013.
And we want to know the difference between this date and today.
sqlite> SELECT julianday() - julianday('2013-01-06');
34.7978485878557
The difference is 34 days. We can use julianday('now') for
better clarity. In other words, we do not need to put
date() or datetime() functions as parameters to julianday()
function.
The SQLite documentation is a great reference and the DateAndTimeFunctions page is a good one to bookmark.
It's also helpful to remember that it's pretty easy to play with queries with the sqlite command line utility:
sqlite> select julianday(datetime('now'));
2454788.09219907
sqlite> select datetime(julianday(datetime('now')));
2008-11-17 14:13:55
This answer is a little long-winded, and the documentation will not tell you this (because they assume you are storing your dates as UTC dates in the database), but the answer to this question depends largely on the timezone that your dates are stored in. You also don't use Date('now'), but use the julianday() function, to calculate both dates back against a common date, then subtract the difference of those results from each other.
If your dates are stored in UTC:
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
This is what the top-ranked answer has, and is also in the documentation. It is only part of the picture, and a very simplistic answer, if you ask me.
If your dates are stored in local time, using the above code will make your answer WRONG by the number of hours your GMT offset is. If you are in the Eastern U.S. like me, which is GMT -5, your result will have 5 hours added onto it. And if you try making DateCreated conform to UTC because julianday('now') goes against a GMT date:
SELECT julianday('now') - julianday(DateCreated, 'utc') FROM Payment;
This has a bug where it will add an hour for a DateCreated that is during Daylight Savings Time (March-November). Say that "now" is at noon on a non-DST day, and you created something back in June (during DST) at noon, your result will give 1 hour apart, instead of 0 hours, for the hours portion. You'd have to write a function in your application's code that is displaying the result to modify the result and subtract an hour from DST dates. I did that, until I realized there's a better solution to that problem that I was having: SQLite vs. Oracle - Calculating date differences - hours
Instead, as was pointed out to me, for dates stored in local time, make both match to local time:
SELECT julianday('now', 'localtime') - julianday(DateCreated) FROM Payment;
Or append 'Z' to local time:
julianday(datetime('now', 'localtime')||'Z') - julianday(CREATED_DATE||'Z')
Both of these seem to compensate and do not add the extra hour for DST dates and do straight subtraction - so that item created at noon on a DST day, when checking at noon on a non-DST day, will not get an extra hour when performing the calculation.
And while I recognize most will say don't store dates in local time in your database, and to store them in UTC so you don't run into this, well not every application has a world-wide audience, and not every programmer wants to go through the conversion of EVERY date in their system to UTC and back again every time they do a GET or SET in the database and deal with figuring out if something is local or in UTC.
Just a note for writing timeclock functions. For those looking for hours worked, a very simple change of this gets the hours plus the minutes are shown as a percentage of 60 as most payroll companies want it.
CAST ((julianday(clockOUT) - julianday(clockIN)) * 24 AS REAL) AS HoursWorked
Clock In Clock Out HoursWorked
2016-08-07 11:56 2016-08-07 18:46 6.83333332836628
Given that your date format follows : "YYYY-MM-DD HH:MM:SS",
if you need to find the difference between two dates in number of months :
(strftime('%m', date1) + 12*strftime('%Y', date1)) -
(strftime('%m', date2) + 12*strftime('%Y', date2))
Firstly, it's not clear what your date format is.
There already is an answer involving strftime("%s").
I like to expand on that answer.
SQLite has only the following storage classes: NULL, INTEGER, REAL, TEXT or BLOB.
To simplify things, I'm going to assume dates are REAL containing the seconds since 1970-01-01.
Here's a sample schema for which I will put in the sample data of "1st December 2018":
CREATE TABLE Payment (DateCreated REAL);
INSERT INTO Payment VALUES (strftime("%s", "2018-12-01"));
Now let's work out the date difference between "1st December 2018" and now (as I write this, it is midday 12th December 2018):
Date difference in days:
SELECT (strftime("%s", "now") - DateCreated) / 86400.0 FROM Payment;
-- Output: 11.066875
Date difference in hours:
SELECT (strftime("%s", "now") - DateCreated) / 3600.0 FROM Payment;
-- Output: 265.606388888889
Date difference in minutes:
SELECT (strftime("%s", "now") - DateCreated) / 60.0 FROM Payment;
-- Output: 15936.4833333333
Date difference in seconds:
SELECT (strftime("%s", "now") - DateCreated) FROM Payment;
-- Output: 956195.0
If you want time in 00:00 format:
I solved it like that:
SELECT strftime('%H:%M',
CAST((julianday(FinishTime) - julianday(StartTime)) AS REAL),
'12:00')
FROM something;
If you want difference in seconds
SELECT strftime('%s', '2019-12-02 12:32:53') - strftime('%s', '2019-12-02 11:32:53')
If you want records in between days,
select count(col_Name) from dataset where cast(julianday("now")- julianday(_Last_updated) as int)<=0;
In my case, I have to calculate the difference in minutes and julianday() does not give an accurate value. Instead, I use strftime():
SELECT (strftime('%s', [UserEnd]) - strftime('%s', [UserStart])) / 60
Both dates are converted to unixtime (seconds), then subtracted to get
value in seconds between the two dates. Next, divide it by 60.
https://www.sqlite.org/cvstrac/wiki?p=DateAndTimeFunctions

Resources