143

I can't seem to get reliable results from the query against a sqlite database using a datetime string as a comparison as so:

select * 
  from table_1 
 where mydate >= '1/1/2009' and mydate <= '5/5/2009'

how should I handle datetime comparisons to sqlite?

update: field mydate is a DateTime datatype

user4157124
  • 2,809
  • 13
  • 27
  • 42
Brad
  • 20,302
  • 36
  • 84
  • 102
  • 1
    What date format is the value stored in your `mydate` column? I'm guessing it is not one of the SQLite supported formats: http://www.sqlite.org/lang_datefunc.html – OMG Ponies Dec 29 '09 at 17:26
  • 1
    OMG, it's a datetime datatype – Brad Dec 29 '09 at 18:33
  • 4
    That use of datetime() will result in the exact value you gave it, there's no reason to use it here: just use the string instead. And if you're only dealing with dates, you should delete the zero time parts---essentially make sure both sides are in the same format. (Otherwise `'2009-11-13'`, for mydate, will be less than `'2009-11-13 00:00:00'`.) –  Dec 29 '09 at 19:02
  • 1
    In order for Visual Studio with SQLite to work for me to run a date/time query, I need to use the `Datetime()` just as @Brad has included in his mention of the solution. Otherwise VS2012 complains. Thank you Brad. – CaptainBli May 03 '13 at 19:31
  • thank you for updating your with the solution. How strange that the default format for dates in .NET will actually result in the opposite for the "<" vs ">". – Dave Friedel Aug 26 '15 at 13:01
  • Word to the wise, do not call your column `Date`, or weird things will happen (i.e. your `where Date < datetime('...');` won't run). – Lightfire228 Feb 27 '18 at 21:30
  • when the month is less than 10 do I should add zero before the month number '2009-09-02 00:00:00' and is this any problem if I delete the hour, minute and second '2009-01-03'? –  Jan 26 '20 at 10:51
  • 10 years later, just wanted to point out, that SqLite does not have a datatype 'datetime': https://www.sqlite.org/datatype3.html. It seems they only have `NULL, INTEGER, REAL, TEXT, BLOB` – Ted Nov 30 '20 at 20:11

14 Answers14

113

To solve this problem, I store dates as YYYYMMDD. Thus, where mydate >= '20090101' and mydate <= '20050505'

It just plain WORKS all the time. You may only need to write a parser to handle how users might enter their dates so you can convert them to YYYYMMDD.

Oleks
  • 31,955
  • 11
  • 77
  • 132
Mark Smith
  • 1,139
  • 2
  • 6
  • 2
  • 3
    Provided the format is standardized, how would having YYYY-MM-DD be different from without the dashes? Wouldn't comparisons end up the same? – Damon Mar 24 '11 at 18:39
  • 2
    @Damon: i think he uses an int for datatype – thumbmunkeys Apr 09 '11 at 11:21
  • 3
    No, these are strings - you can see it at the quotes - But this is the great idea: With this order **YY MM DD** it's possible to compare the dates. @Damon it also should work with the dashes! – Sedat Kilinc Nov 24 '11 at 17:15
  • 1
    I wonder if i can do the same thing if i use the format yyyyMMddHHmmss to store, so that i can include the time part as well. Would it cause an overflow or something? – faizal Aug 25 '14 at 09:44
  • 2
    I use: yyyyMMddHHmm with no problem, I'd expect yyyyMMddHHmmss to work the same – Steve Byrne Aug 15 '16 at 09:34
  • How do you specify a format for storing a date when using the datatype DATE? Or are you storing the date das TEXT? – Sandrogo Feb 19 '19 at 21:24
69

SQLite doesn't have dedicated datetime types, but does have a few datetime functions. Follow the string representation formats (actually only formats 1-10) understood by those functions (storing the value as a string) and then you can use them, plus lexicographical comparison on the strings will match datetime comparison (as long as you don't try to compare dates to times or datetimes to times, which doesn't make a whole lot of sense anyway).

Depending on which language you use, you can even get automatic conversion. (Which doesn't apply to comparisons in SQL statements like the example, but will make your life easier.)

  • 17
    For all those reading the first sentence, in '17 SQLite does have `date` and `datetime` – alisianoi Jun 21 '17 at 13:29
  • 4
    Yesterday was reading about type affinity here: https://www.sqlite.org/datatype3.html Basically, if you need a date, you declare a `date` (or `datetime`) on the column which internally is treated as `text`. That fits my needs. – alisianoi Jun 22 '17 at 13:27
  • 3
    3.5 years, later, when I read https://www.sqlite.org/datatype3.html: "SQLite does not have a storage class set aside for storing dates and/or times" =) – Ted Nov 30 '20 at 20:13
  • @alisianoi what do you mean by "declare" ? – GintsGints May 16 '23 at 08:06
50

I had the same issue recently, and I solved it like this:

SELECT * FROM table WHERE 
    strftime('%s', date) BETWEEN strftime('%s', start_date) AND strftime('%s', end_date)
Cedric H.
  • 7,980
  • 10
  • 55
  • 82
Simon
  • 675
  • 5
  • 8
  • %s must be enclosed between single quote characters, i.e.: strftime('%s', date) – mvladic Jun 04 '12 at 09:28
  • It works. Modified solution to select all rows after certain date: SELECT * FROM table WHERE strftime('%s', added) > strftime('%s', "2017-01-01 00:00:00") – New Progammer Aug 18 '17 at 08:11
  • 1
    I am evaluating using `strftime` in a WHERE clause like in this example, and I have a question: Is it efficient to use `strftime` like this? Is it evaluated once for every row or once per query? – Alvaro Gutierrez Perez Nov 20 '17 at 08:32
  • 5
    What is the type of `date`, `start_date` and `end_date` here? – ericn Aug 27 '20 at 02:01
29

The following is working fine for me using SQLite:

SELECT * 
    FROM ingresosgastos 
    WHERE fecharegistro BETWEEN "2010-01-01" AND "2013-01-01"
Roddy of the Frozen Peas
  • 14,380
  • 9
  • 49
  • 99
ifredy
  • 299
  • 3
  • 2
  • This worked for me in iOS, Objective-C My Query is as follows: SELECT COUNT(carSold) FROM cars_sales_tbl WHERE date BETWEEN '2015-04-01' AND '2015-04-30' AND carType = "Hybrid" – Randika Vishman Apr 28 '15 at 14:56
15

Following worked for me.

SELECT *
FROM table_log
WHERE DATE(start_time) <= '2017-01-09' AND DATE(start_time) >= '2016-12-21'
11

Sqlite can not compare on dates. we need to convert into seconds and cast it as integer.

Example

SELECT * FROM Table  
WHERE  
CAST(strftime('%s', date_field)  AS  integer) <=CAST(strftime('%s', '2015-01-01')  AS  integer) ;
Hardeep Singh
  • 743
  • 1
  • 8
  • 18
10

I have a situation where I want data from up to two days ago and up until the end of today. I arrived at the following.

WHERE dateTimeRecorded between date('now', 'start of day','-2 days') 
                           and date('now', 'start of day', '+1 day') 

Ok, technically I also pull in midnight on tomorrow like the original poster, if there was any data, but my data is all historical.

The key thing to remember, the initial poster excluded all data after 2009-11-15 00:00:00. So, any data that was recorded at midnight on the 15th was included but any data after midnight on the 15th was not. If their query was,

select * 
  from table_1 
  where mydate between Datetime('2009-11-13 00:00:00') 
                   and Datetime('2009-11-15 23:59:59')

Use of the between clause for clarity.

It would have been slightly better. It still does not take into account leap seconds in which an hour can actually have more than 60 seconds, but good enough for discussions here :)

Lyall Pearce
  • 181
  • 1
  • 5
4

I had to store the time with the time-zone information in it, and was able to get queries working with the following format:

"SELECT * FROM events WHERE datetime(date_added) BETWEEN 
      datetime('2015-03-06 20:11:00 -04:00') AND datetime('2015-03-06 20:13:00 -04:00')"

The time is stored in the database as regular TEXT in the following format:

2015-03-06 20:12:15 -04:00
Eternal21
  • 4,190
  • 2
  • 48
  • 63
4

Right now i am developing using System.Data.SQlite NuGet package (version 1.0.109.2). Which using SQLite version 3.24.0.

And this works for me.

SELECT * FROM tables WHERE datetime 
BETWEEN '2018-10-01 00:00:00' AND '2018-10-10 23:59:59';

I don't need to use the datetime() function. Perhaps they already updated the SQL query on that SQLite version.

Aruman
  • 1,646
  • 1
  • 12
  • 12
3

Below are the methods to compare the dates but before that we need to identify the format of date stored in DB

I have dates stored in MM/DD/YYYY HH:MM format so it has to be compared in that format

  1. Below query compares the convert the date into MM/DD/YYY format and get data from last five days till today. BETWEEN operator will help and you can simply specify start date AND end date.

    select * from myTable where myColumn BETWEEN strftime('%m/%d/%Y %H:%M', datetime('now','localtime'), '-5 day') AND strftime('%m/%d/%Y %H:%M',datetime('now','localtime')); 
    
  2. Below query will use greater than operator (>).

      select * from myTable where myColumn > strftime('%m/%d/%Y %H:%M', datetime('now','localtime'), '-5 day');  

All the computation I have done is using current time, you can change the format and date as per your need.

Hope this will help you

Summved

Summved Jain
  • 872
  • 2
  • 18
  • 21
1

You could also write up your own user functions to handle dates in the format you choose. SQLite has a fairly simple method for writing your own user functions. For example, I wrote a few to add time durations together.

J. Polfer
  • 12,251
  • 10
  • 54
  • 83
1

My query I did as follows:

SELECT COUNT(carSold) 
FROM cars_sales_tbl
WHERE date
BETWEEN '2015-04-01' AND '2015-04-30'
AND carType = "Hybrid"

I got the hint by @ifredy's answer. The all I did is, I wanted this query to be run in iOS, using Objective-C. And it works!

Hope someone who does iOS Development, will get use out of this answer too!

Randika Vishman
  • 7,983
  • 3
  • 57
  • 80
0

Here is a working example in C# in three ways:

  string tableName = "TestTable";

  var startDate = DateTime.Today.ToString("yyyy-MM-dd 00:00:00"); \\From today midnight
  var endDate = date.AddDays(1).ToString("yyyy-MM-dd HH:mm:ss"); \\ Whole day

  string way1 /*long way*/ = $"SELECT * FROM {tableName} WHERE strftime(\'%s\', DateTime) 
  BETWEEN strftime('%s', \'{startDate}\') AND strftime('%s', \'{endDate}\')";
  
  string way2= $"SELECT * FROM {tableName} WHERE DateTime BETWEEN \'{startDate}\' AND \'{endDate}\'";

  string way3= $"SELECT * FROM {tableName} WHERE DateTime >= \'{startDate}\' AND DateTime <=\'{endDate}\'";

A. Dzebo
  • 558
  • 6
  • 13
0

select * from table_1 where date(mydate) >= '1/1/2009' and date(mydate) <= '5/5/2009'

This work for me

jimm
  • 1