Does sqlite3 has analogue MySQL's CONVERT_TZ function? - sqlite

I get exception when try to use CONVERT_TZ in RoR project:
SQLite3::SQLException: no such function: CONVERT_TZ
Is there some function in sqlite for convert timezone in a query?

To convert from UTC+0 to UTC+3:
SELECT datetime(columnName, '+3 hour') || '+03:00' AS myDate FROM tableName;
Explanation:
datetime(columnName, '+3 hour')
Above does the translation of hours, it simply tells SQLite to add 3 hours to the initial date. This would not be enough, because it only modifies date, without really telling that the timezone has changed, so we can do it manually, by appending '+03:00' to the final date string.
It makes the following conversion from 2015-03-05 15:03:43 to 2015-03-05 18:03:43+03:00
That means that the date format will change from YYYY-MM-DD HH:MM:SS to YYYY-MM-DD HH:MM:SS[+/-]HH:MM, which is a correct datetime format for SQLite, according to its documentation.
Read SQLite's documentation about date functions for any details, or just ask in comments and I can try to help even further. I don't want to paste the entire documentation page here.

Related

How can I convert timestamps to dates in SQLite?

How can I convert timestamps to dates in SQLite?
The following code only produces a Timestamp column and a Date columns with NULL values. The the SQL code needs to convert from a "08/28/2020 8:00" format.
SQL CODE:
'''Select Timestamp, strftime('%m-%d-%Y', Timestamp) as Date
FROM Room_Data'''
The SQLite documentation is pretty clear, but I can't seem to get the desired result.
The strftime is meant to format a date, rather than perform conversion.
In the meantime you could try something like that to gather the pieces:
SELECT Timestamp,
SUBSTR(c,7,4) || '-' || SUBSTR(Timestamp,1,2) || '-' || SUBSTR(Timestamp,4,2) as Date
FROM Room_Data
Since SQlite doesn't really have the concept of a date, unlike other DBMS, the best choice would be to convert your dates to integer, either as Unix timestamps or in string form (YYYY-MM-DD) but storing dates as integer like 20201010 would be acceptable too.
NB: be careful with names like Timestamp or Date, they are reserved keywords in many programming languages and DBMSes.
The original code won't work in Windows 10 for some reason. Trying this from a Linux distro (Kubuntu, in this case) seems to resolve the issue. In Windows, the date needs to be converted to a '2020-01-01' format to actually work.
SQLite is amazing, but not sure why functionality changes for Windows 10. Feel free to comment if you know more about the differences.

Sqlite SELECT * for Last 30 days

I have a SQLite DB with the following columns:
File, Date_created, Owner
How do I get the list of files created in the last 30 days?
I tried the following, but it didn't limit the result. The list came back with files created 2 years ago!
SELECT * FROM Table1 WHERE Date_created > (SELECT DATETIME('now', '-30 day'))
Also, not sure if it matters, but my Created_date column is in the following date format: dd/mm/yyyy hh:mm:ss
SQLite doesn't have a native datetime data type, so that comparison's going to be on text. If your records are in DD/MM/YYYY format, you'll end up with comparisons like "07/03/2020" > "2020-06-07" which make little sense.
If you opt to store your datetimes as text, you must use a format that's lexicographically orderable. A great standard format that exhibits this property (if every piece of data has the same timezone, anyway) is ISO 8601, e.g. 2020-07-07 15:04:14+0300 at the time of writing in my timezone. As an aside, even xkcd recommends ISO 8601.
If you opt to store your datetimes as numbers, you can store them as either UNIX time, or maybe, if you're feeling adventurous, as e.g. the number 20200707150414. Do remember neither of these numeric options store timezone information, if that's important to your application.
As an aside,
SELECT * FROM Table1 WHERE Date_created > DATETIME('now', '-30 day')
is enough :)
Something like this might be what you are looking for, it's something that's come up in my head, haven't tested it.
Basically you're going 30 days backwards by Date_created.
SELECT * FROM Table1
WHERE DATEDIFF(DAY, DATEADD(DAY, -30, GETDATE()), Date_created) > 0

Converting Datetimes returns Null

I'm trying to convert a datetime that looks like this: 2017-09-19T07:00:00-07:00 into EST, but i keep getting Null values when using the hive built in UTC conversion.
I've tried using a regular expression to parse the date:
date_format(from_unixtime(unix_timestamp(2017-09-19T07:00:00-07:00, "yyyy-MM-dd'T'HH:mm:ss")
- (cast(regexp_extract(regexp_extract(2017-09-19T07:00:00-07:00, '(-[0-9][0-9]:[0-9][0-9])$', 1),'(-[0-9][0-9])',1) as int)*3600) -18000),'YYYY-MM-dd HH:mm')
but that's not good, since there's an hourly difference based on the time of year.
I've also tried:
FROM_UTC_TIMESTAMP(UNIX_TIMESTAMP(2017-09-19T07:00:00-07:00, "yyyy-MM-dd'T'hh:mm:ss:SSS'ZZZZZ'") * 1000, 'EST')
and
FROM_UTC_TIMESTAMP(UNIX_TIMESTAMP(2017-09-19T07:00:00-07:00, "yyyy-MM-dd'T'hh:mm:ss:SSS'Z'") * 1000, 'EST')
but that appears to not work either. What am I doing wrong?
I think that this method needs the date as a string like this:
date_format(from_unixtime(unix_timestamp('2017-09-19T07:00:00-07:00', "yyyy-MM-dd'T'HH:mm:ss")
Normally, the date formats are for strings, not for integers or numbers.
I found the answer on my own by combining the two ways of running the query.
date_format(
FROM_UTC_TIMESTAMP(
(unix_timestamp('2017-09-19T07:00:00-07:00', "yyyy-MM-dd'T'HH:mm:ss")
+ (cast(
regexp_extract(
regexp_extract('2017-09-19T07:00:00-07:00', '(-[0-9][0-9]:[0-9][0-9])$',1),'(-[0-9][0-9])',1) as int)
*-3600)
)*1000 ,'America/New York')
,'YYYY-MM-dd HH:mm:ss')
You are getting NULL because the pattern (format of the date and time) you have provided is not matching with the actual date time value. Correcting the date time format in your query would resolve this issue:
select from_unixtime(UNIX_TIMESTAMP("2017-09-19T07:00:00-07:00", "yyyy-MM-dd'T'HH:mm:ssXXX"), "yyyy-MM-dd HH:mm:ss");
Check out this link to know more about the date time patterns: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

Where do I find the reference for TO_DATE format string

I need to convert a string formatted as MM/DD/YYYY HH:MI plus AM/PM, but can't find a complete reference to the format string to find how to specify the AM/PM part.
I would certainly appreciate information on how to do this, but would appreciate a link to a good source of documentation for this even more.
:EDIT
SELECT top 1
v.CalendarDateTime
,TO_TIMESTAMP(v.CalendarDateTime,'MM/DD/YYYY HH:MIAM') as CalendarDateTimeTS
--,CAST(TO_TIMESTAMP(v.CalendarDateTime,'MM/DD/YYYY HH:MIAM') AS TIMESTAMP(0) FORMAT 'MM/DD/YYYYBHH:MIBT') AS CalendarDateTimeTS2
12/03/2015 03:00AM 12/3/2015 03:00:00.000000
The commented out line produces a "DateTime field overflow" error.
You probably want TO_TIMESTAMP instead of TO_DATE.
The only bad thing about the Oracle function is the resulting datatype of TIMESTAMP(6) which can't be changed:
TO_TIMESTAMP('12/03/2015 03:00AM', 'MM/DD/YYYY HH:MIAM')
Using Teradata's FORMAT you can specify the timestamp precision, but it's less flexible than Oracle's, the string must match the format exactly:
CAST('12/03/2015 03:00AM' AS TIMESTAMP(0) FORMAT 'MM/DD/YYYYbHH:MIT')
On the Teradata site you'll find the (slow) online docu, e.g. TO_DATE formats or Teradata FORMATs. Of course you should download the full documentation CD for your release.
Please tell us at least which programming language are you using.
Normally it would be something like "MM/DD/YYYY HH:MI a" but we need to know first you language.

I need a sqlite equivalent of the folling msaccess query

Select distinct Format(DateAdd(""s""," & columnname & ",""1/1/1980 12:00:00 AM""), 'dd-MMM-yyyy') as A
I have assumed that the seconds to add and the original date are hard coded values below whilst awaiting clarifications requested in the comments.
To add a number of seconds to a date you can use:
select datetime('1980-01-01 00:00:00', "345000 seconds");
This gives the result: 1980-01-04 23:50:00
The example above is just under 4 days in seconds, if you want to truncate the result to just the date as implied by the query in your questions then you can wrap this inside a date function. However, this would give the result in the format "YYYY-MM-DD" rather than "DD-MMM-YYYY" as your access query does.
Unfortunately I cannot find any native SQLite function to convert a numeric month value to mmm format. You can do this manually with replace (similar to the answer to this question), but this is a bit messy.
If you are happy to live with the numeric months then you can simply use:
select strftime('%d-%m-%Y', '1980-01-01 00:00:00', "345000 seconds");
This gives the result: 04-01-1980
More information on the SQLite date / time functions can be found here.

Resources