How to search in sqlite for hour regardless of timezone? - sqlite

I wanted to make a database containing my blood sugar levels (I have diabetes).
For each entry, the timestamp of the measurement is saved like this "2020-05-02 12:11:13 +0200".
Now I want to plot the data by the hour (get the same hour of different days).
If I have traveled to a different timezone the entries for this day will be n hours of.
For example, if I want to get all entries for 13:00 I will get the values that were measured at 04:00 in California and 20:00 in Tokyo. But I want the 13:00 o'Clock values from all these places/timezones.
Is this possible, or should I just create a separate column for UTC and local time?
I already tried things like these:
... WHERE strftime('%H', date) = '13'
... WHERE strftime('%H', date,"UTC") = '13'
... WHERE time(date)>= time('00:00:00','+13 hour')
Solution:
See #forpas answer.
I modified it a little
strftime('%H',datetime( substr(date, 1, 19))) = '10'

You need string functions to extract the YYYY-MM-DD hh:mm:ss part of the date and add the offset which may include minutes:
where
strftime(
'%H',
datetime(
substr(date, 1, 19),
substr(date, 21, 3) || ' hour',
substr(date, 21, 1) || substr(date, -2) || ' minute'
)
) = '13'

apparently sqlite doesn't understand the format of your timestamp, because of the timezone format at the end (+0200)
not sure if you must use da date/time function, but you can easily subtract the hour with substr;
... WHERE substr(tm, 12, 2) = '13'

Related

SQlite REPLACE issue

I have a date in the format 'MM/DD/YYYY'. I need the month, day, and year to be separated by : or - for functions like strftime to work in sqlite. I'm attempting to use REPLACE but it won't work on '/'.
Any help is appreciated.
UPDATE table SET date = REPLACE(date,'/','-')
Even if you replace / with -, the date functions of SQLite will not work with your dates.
The only valid date format for SQLite is YYYY-MM-DD.
Update the column date to that format like this:
UPDATE tablename
SET date = SUBSTR(date, -4) || '-' || SUBSTR(date, 1, 2) || '-' || SUBSTR(date, 4, 2);
See the demo.

I inserted rows with the UTC date into an int column in my database. How can I get just the rows that were inserted in the last 24 hours?

Here's the insert that I used:
db2.Insert(new QuizHistory()
{
QuizId = quiz,
Cards = 0,
Points = points,
UtcNow = (int)Math.Truncate(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds),
Viewed = 1,
Deck = deck
});
I tried looking at the different sql functions but now I am more confused than ever.
select * QuizHistory << but just for the last 24 hours.
As you are storing the date as seconds since january 1, 1970, a solution would be to use strftime :
select *
from QuizHistory
where UtcNow > strftime('%s', 'now', '-1 day')
i.e. with %s as format (seconds since 1970-01-01), for the now date with a -1 day modifier

Get days until future event in SQLite

Trying to get several things from a SQLite table with names and dates of birth and am having trouble getting the # of days until a person's next birthday. Dates are stored as SQLite's TEXT data type in format '%Y-%m-%d 00:00:00'.
I can get age:
SELECT ((strftime('%s', 'now') - strftime('%s', dob)) / 31536000) AS age
I like this solution for showing the closest birthdays first:
ORDER BY SUBSTR(date('now'), 6) > SUBSTR(dob, 6), SUBSTR(dob, 6) ASC
But I'm breaking my brain over getting the days until the next birthday. My latest attempt is taking the julianday of the substring of the day and month from dob and concatenate it with the current year to compare against julianday() and put in conditionals to take the year change into account, but I haven't worked that out yet and I'm hoping someone has a more elegant solution.
Have made my hideous solution work, so here it is:
SELECT
CASE WHEN
julianday((SUBSTR(date('now'), 1, 5) || SUBSTR(dob, 6, 5))) > julianday('now')
THEN CAST(ROUND(
julianday((SUBSTR(date('now'), 1, 5) || SUBSTR(dob, 6, 5))) - julianday('now'), 0) AS INTEGER)
ELSE CAST(ROUND((
julianday(SUBSTR(date('now'), 1, 5) || '12-31') - julianday('now')) + (
julianday(SUBSTR(date('now'), 1, 5) || SUBSTR(dob, 6, 5)) - julianday(SUBSTR(date('now'), 1, 5) || '01-01')), 0) AS INTEGER)
END
AS dub FROM person;
Will only have to put in another conditional to improve the rounding.

How to count days between date range with a specifific day?

How to count days between date range with a specific day?
Example:
START_DT = January 1, 2014;
END_DT = January 31, 2014;
Day = :SampleDay
Sample Result:
Monday = 4,
Tuesday = 4,
Wednesday = 5
Please help. :|
Are you looking for something like this,
WITH t(date1, date2) AS
(
SELECT to_date('01/01/2014', 'dd/mm/yyyy'),
to_date('31/01/2014','dd/mm/yyyy')+1 -- Adding 1 to calculate the last day too.
FROM DUAL
)
SELECT count(days) day_count, day
DAY
FROM(
SELECT date1 + LEVEL -1 days,
to_char(date1 + LEVEL -1, 'FmDay') DAY, --Use `FmDay`, this will remove the Embedded spaces.
to_char(date1 + LEVEL -1, 'D') DAY#
FROM t
CONNECT BY LEVEL <= date2 - date1
)
WHERE day = 'Monday' --Filter with day, if you want to get the count for a specific day.
GROUP BY DAY, day#
ORDER BY day#;
You wont have a direct solution to this. In oracle you have this form to know what day of the week is a specific date:
to_char(to_date('01012014', 'ddmmyyyy'), 'Day')
I would recommend to you to make a store procedure with a simple algorithm which receive that three parameters and then display the information you need. Put it in a query and it is done.

SQLite ISO (ie European style) week numbers

I want to return ISO standard week numbers (ie week 1-52/53) from a date.
I have tried using the built in function strftime, but with no success.
Can anyone suggest a way without having to write a custom C or other function.
I know this is an old question, but recently I was looking for an efficient solution for the same problem, and this is what I came up with:
SELECT
my_date,
(strftime('%j', date(my_date, '-3 days', 'weekday 4')) - 1) / 7 + 1 as iso_week
FROM my_table;
The basic idea is to calculate the ISO week number by simply performing integer division of the day of year of the Thursday of the date being looked up (my_date) by 7, giving a result between 0 and 52, and then adding 1 to it. And the subtraction by 1 just before the division is there just for the alignment of the division: Thursday of week 1, for example, can have a day of year between 1 and 7, and we want the result of the division to be 0 in all cases, so we need to subtract 1 from the day of year before dividing it by 7.
What specifically did you try?
This works for me (using built-in SQLite from Python REPL):
import sqlite3
c = sqlite3.connect(':memory:')
c.execute('''create table t (c);''')
c.execute('''insert into t values ('2012-01-01');''')
c.execute('''select c, strftime('%W',c) from t;''').fetchone()
# -> (u'2012-01-01', u'00')
OK, so I managed to answer my own question. For anyone who might need a similar solution, this is what I came up with. Please note, I do not have an IT background and my SQL is self taught.
General process
Get the Thursday of the week the date belongs too.
Get the 4th of January of the year of that Thursday.
Get the Thursday of the week the 4th January date belongs too.
Subtract Step 2 with Step 3, divide by 7 and add 1.
Translated into SQLite....
SELECT
date,
CASE CAST (strftime('%w', wknumjanfourth) AS INTEGER)
WHEN 0 THEN ((JULIANDAY(datesThur) - JULIANDAY(strftime("%s", wknumjanfourth) - 259200, 'unixepoch')) / 7) + 1
ELSE ((JULIANDAY(datesThur) - JULIANDAY(DATE(strftime("%s", wknumjanfourth) - (86400 * (strftime('%w', wknumjanfourth) - 1)), 'unixepoch'), '+3 day')) / 7) + 1
END AS weeknum
FROM
(
SELECT
date,
datesThur,
DATE(datesThur,'start of year','+3 day') AS wknumjanfourth
FROM
(SELECT
date,
CASE CAST (strftime('%w', date) AS INTEGER)
WHEN 0 THEN DATE(strftime("%s", date) - 259200, 'unixepoch')
ELSE DATE(DATE(strftime("%s", date) - (86400 * (strftime('%w', date) - 1)), 'unixepoch'), '+3 day')
END AS datesThur
FROM TEST
))
If anyone can improve this SQL, I would appreciate the feedback.

Resources