Negative dates in sqllite database - sqlite

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.

Related

How to get the last date of the week in sqlite3?

Let's say I have a column with values in the format of a datetime '2021-07-01 00:00:00.000', how do I get the last date of the week (Sunday) for any datetime such as this in sqlite3? The day of the last date of the week is a Sunday.
So the answer for this date would want something like 2021-07-04 or 2021/07/04 (removing the time part) which is the date of the Sunday for the week the date 2021-07-01 is belonging to.
I know how this can be done in sqlserver but I do not know how to do it in sqlite.
Could someone please assist me on this? Let me know if you need more clarification.
Here is my attempt on sqlserver, but i need to get the same result in sqlite
SELECT
somedate,
CONVERT(VARCHAR(10),DATEADD(DAY, 7 - DATEPART(WEEKDAY, [somedate]), [somedate]),111) AS Last_Date_Of_Week
FROM table
apparently i can't do this in sqlite because sqlite does not have an official datetime type.
Sqlite date and time functions consider Sunday to be the first day of the week, and have a weekday modifier to advance a given timestamp to the given day of the week (Using 0-based indexing from Sunday). So:
sqlite> SELECT date('2021-07-01 00:00:00.000', 'weekday 0');
date('2021-07-01 00:00:00.000', 'weekday 0')
--------------------------------------------
2021-07-04

Does Sqlite3 Understand 12 Hours time format?

I'm create a Table as follows:
CREATE TABLE IF NOT EXISTS problem(`row_id` INTEGER PRIMARY KEY, `datetime` TEXT)
I insert the values into table
INSERT INTO problem(`row_id`, `datetime`) VALUES
(1, '2021-01-03 12:50 PM'),
(2, '2021-01-03 04:55 PM');
Select the values ordered by column name
SELECT *FROM problem ORDER BY `datetime`
Reselt is here:
row_id datetime
2 2021-01-03 04:55 PM
1 2021-01-03 12:50 PM
In my view, row id 1 will be the first item and row id 2 will be the second entry.
If it does not understand 12 hours time what's the solution?
Does Sqlite3 Understand 12 Hours time format?
No, it understands 24 hour time format (see link below).
If it does not understand 12 hours time what's the solution?
The correct solution would be to store the data in a recognized format as per https://sqlite.org/lang_datefunc.html#time_values
Using a recognised format means that you can then take advantage of SQLite knowing that the column is a date/time/datetime column and thus utilise date time functions as well as being suitable for ordering and comparison.
An example, utilising your dates (note the use of 24 hour times when storing) to get the dates in the 12 hour format based upon 12:00 being PM is :-
DROP TABLE IF EXISTS problem;
CREATE TABLE IF NOT EXISTS problem(`row_id` INTEGER PRIMARY KEY, `datetime` TEXT);
INSERT INTO problem(`row_id`, `datetime`) VALUES
(1, '2021-01-03 12:50'),
(2, '2021-01-03 10:50'),
(3, '2021-01-03 13:55'),
(4, '2021-01-03 16:55'),
(5, '2021-01-03 00:55');
SELECT `row_id`,
date(`datetime`)||
CASE
/* Handle times that are 13:00 or greater i.e. use PM and subtract 12 hours from the stored time */
WHEN time(`datetime`) > '12:59'
THEN ' '||strftime('%H:%M',`datetime`,'-12 hours')||' PM'
/* Handle times that have 12 as the hour i.e. use PM with stored time */
WHEN time(`datetime`) > '11:59'
THEN ' '||strftime('%H:%M',`datetime`)||' PM'
/* ELSE use AM with stored time */
ELSE ' ' || strftime('%H:%M',`datetime`)||' AM'
END
AS `newdatetime` /* Note alias otherwise column name is generated according to column selection code */
FROM problem ORDER BY `datetime`;
Note that the order is as per the datetime column which being in a sortable format is always correct as the 24 hour format is used.
Note that the precision is only suitable for hh:mm e.g. if seconds then 12:59 should be 12:59:59 .....
The result of running the above is :-
The above utilises some of the Date Time Functions found at https://sqlite.org/lang_datefunc.html
The date function returns the date in yyyy-mm-dd format,
The time
function returns the time in hh:mm:ss format,
strftime is the
underlying function that can return a value in many formats based
upon a formatting string and modifiers.
All 3 use a take a time_value
(often the respective column containing the time).
You could perhaps simplify matters by utilising a function in whatever programming language your are using that converts from 24 hour to 12 hour. This could reduce the need for the complicated queries.

SQLite, leap year check, and day counting

I am trying to write some sqlite code that will check if the date range include February 29th and if so, divide the total number of days elapsed by 366. Otherwise, divide by 365. I've only included one of the two queries as fixing one essentially fixes the other.
Thank you for your help.
UPDATE table SET "Date Adjust" = (strftime('%Y-%m-%d',"End Date") -
strftime('%Y-%m-%d',"Start Date"))/366
WHERE "2020-02-29" BETWEEN strftime('%Y-%m-%d',"Start Date") AND strftime('%Y-%m-%d',"End Date")
If you want to get the difference in days between 2 dates you should not subtract the result of strftime().
The function strftime() returns a formatted date as a string.
You can use the function julianday():
UPDATE tablename
SET "Date Adjust" =
(julianday('%Y-%m-%d',"End Date") - julianday('%Y-%m-%d',"Start Date")) /
(365 + ("2020-02-29" BETWEEN strftime('%Y-%m-%d', "Start Date") AND strftime('%Y-%m-%d', "End Date")))
The value returned by julianday() is a floating point number, so if you want the result as an integer you may round it with the function ROUND().
For this statement to work your dates must be in the only valid date format for SQLite which is YYYY-MM-DD.
The above statement will work for both cases: leap year or not.

SQLite strftime() weekday

I have been trying with no success to to count how many values were created in a specific week day:
SELECT count(*) as count FROM packets WHERE strftime("%w", timeIn) = '1';
I have this values in timeIn
1472434822.60033
1472434829.12632
1472434962.34593
I don't know what I am doing wrong here.
furthermore, if I use this:
SELECT count(*) as count FROM packets WHERE strftime("%w", timeIn) = '6';
I get
2
which makes no sense. Thank you in advance.
You appear to be storing the date as the number of seconds since 1970 (the Unix epoch) - a common representation. The time strings accepted by the SQLite date functions (see the Time Strings section) default to interpreting numeric time strings as a Julian day numbers:
Similarly, format 12 is shown with 10 significant digits, but the date/time functions will really accept as many or as few digits as are necessary to represent the Julian day number.
You can see this with the following SELECT:
SELECT strftime('%Y-%m-%d', 1472428800.6) AS t
the result of which is:
4026-48-26
For your date representation to be interpreted as a Unix epoch, you need to include 'unixepoch' in the strftime call:
SELECT strftime('%Y-%m-%d', 1472428800.6, 'unixepoch') AS t
which returns:
2016-08-29
If you modify your SELECT to be:
SELECT count(*) as count FROM packets WHERE strftime("%w", timeIn, 'unixepoch') = '6'
you should see results more inline with your expectations.

Sort date in sqlite

I want to select the dates in ascending order. Dates are stored in dd-MMM-yy(02-Mar-12) format. Here is my query:
SELECT EventDate,Event,ID from EventCalenderTable Order By EventDate ASC
output is:
10-03-12
12-02-12
15-01-12
18-07-12
But the output should like:
15-01-12
12-02-12
10-03-12
18-07-12
Event Date is date datatype.
I have seen number of post about storing date in sql. I noticed that Convert function done the tricks in sql server. But how can I do this in Sqlite??
Thanks in advance.
SQLite only knows three date formats:
Text ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS")
Real Julian day numbers since November 24, 4714 B.C
Integer number of seconds since 1970-01-01 00:00:00 UTC
SQLite does have five date/time functions for converting between formats.

Resources