SQLite date comparison on non-valid Timestring formats - c#

I want to get entries from a SQLite database by date.
SQLite valid timestring formats are listed here as:
YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
HH:MM
HH:MM:SS
HH:MM:SS.SSS
now
DDDD.DDDD
I have another format in the database that is D/M/YYYY
Is there a way to compare dates in this database (and select entries accordingly) without having to select, parse and compare all the DateTime objects from all rows in the table?

you can compare dates in SQLITE by using some conventons
try to save dates in the same Format
SQLITE uses 3 Dateformats (not realy Formats but used ones)
* String as mentioned (YYYY-MM-DD [HH:MI:SS])
* Integer
* Real
I mostly use real for date-fields which are used for comparing
They have to be saved by the julianday() Function
The biggest Problem is, SQLITE has only a small date Converter function, so not well-formed dates can't or will not be correctly converted

Sqlite doesn't support comparing dates (and datetimes) specifically "out of the box".
As far as I know, you have three options (in order of my preference):
Use a format that is suited for string-based comparisons (e.g. YYYYMMDD). Here is something to get you started:
sqlite> create table foo (d TEXT);
sqlite> insert into foo values ('02/01/2012');
sqlite> select substr(d, 7, 4) || substr(d, 1, 2) || substr(d, 4, 2) from foo;
20120201
Use convoluted SQL to get it done using "out of the box" functions.
Create a function yourself.

I made a really FAST query and I am proud of it :p. So here it is:
public static string FromClausePartForDateComparisson(string tableName, string dateFieldName, string idFieldName, DateTime from, DateTime to)
{
string clause = string.Format(#" from
(SELECT {0} as filteredId,
Substr('00'|| -- make day with two digits
CASE Substr({1}.{2}, 3, 1)
WHEN '/' THEN Substr({1}.{2}, 1, 2)
ELSE Substr({1}.{2}, 1, 1)
END, -2, 2) AS DAY,
Substr('00'|| -- make month with two digits
CASE Length({1}.{2})
WHEN 8 THEN Substr({1}.{2}, 3, 1)
WHEN 9 THEN CASE Substr({1}.{2}, 3, 1)
WHEN '/' THEN Substr({1}.{2}, 4, 1)
ELSE Substr({1}.{2}, 3, 2)
END
WHEN 10 THEN Substr({1}.{2}, 4, 2)
END, -2, 2) AS MONTH,
Substr({1}.{2}, Length({1}.{2}) - 3, 4) AS YEAR
FROM {1}
WHERE Strftime('%Y%m%d', YEAR||'-'||MONTH||'-'|| DAY) BETWEEN
Strftime('%Y%m%d', '{3}') AND
Strftime('%Y%m%d', '{4}')) AS filteredtable
INNER JOIN {1} ON filteredtable.filteredId = {1}.{0} ", idFieldName, tableName, dateFieldName, from.ToString("yyyy-MM-dd"), to.ToString("yyyy-MM-dd"));
return clause;
}
And it is being used as:
var selectCommand = new SQLiteCommand("SELECT * " +
FromClausePartForDateComparisson("TABLENAME", "DATE", "ID", from, to) +
#"WHERE ID_TABLENAME=#Id";

Related

7-digit Julian Date to Normal Calendar Date

How do I convert a 7-digit Julian Date (2016092) to a regular Calendar date (MM-DD-YYYY)?
I was thinking of taking the last three digits and converting it to a regular date then appending the first four digits as the year but I'd have to consider leap years.
Expected output: 04-01-2016
My current (SQL) code which solves the problem is
DECLARE #dt char(7)
SET #dt = 2016092
SELECT DATEADD(dd, CAST(RIGHT(#dt, 3) AS int) - 1, CAST(LEFT(#dt, 4) AS datetime))
How can I implement it on C#?
You don't have any kind of Julian Day (Date) format which is
https://en.wikipedia.org/wiki/Julian_day
But a kind of custom format which can be reconstructed from the sql provided:
year * 1000 + days from 1st Jan + 1
So 2016092 means year 2016 and 092 - 1 = 91st day from the 1st of Jan (1st of Apr)
Implementation:
int source = 2016092;
DateTime result = new DateTime(source / 1000, 1, 1).AddDays(source % 1000 - 1);
Console.WriteLine($"{result:MM-dd-yyyy}");
Outcome:
04-01-2016

Compare date in specific format in LINQ

i often compare date this way by in-line sql.
SELECT * FROM dbo.tbl_MyTable
WHERE
CONVERT(VARCHAR, DateTimeValueColumn, 112) >= CONVERT(VARCHAR, '20150101', 112) AND
CONVERT(VARCHAR, DateTimeValueColumn, 112) <= CONVERT(VARCHAR, '20150201', 112)
how could i instruct LINQ to generate the above SQL for date comparison. looking for sample code to achieve this. thanks
It would have been easier to answer if you actually told wanted to do: comparing only the dart part of timestamps. You convert them to format 112 (yyyyMMdd) in order to achieve that.
If you use LINQ queries you'll get DateTime objects for datetime or datetime2 columns. To compare the date part you can simply use the Date property of the DateTime objects, e.g.
[...]
where row.DateTimeColumn.Date >= new DateTime(2015, 1, 1) &&
row.DateTimeColumn.Date <= new DateTime(2015, 2, 1)

How to select current dates from current month

I would like to retrieve the data between 1 -30 of the current month [ i am using MSACCESS Dbase to do so] Below is the query that i am trying --
SELECT count(usercategory) as category_count ,usercategory FROM user_category
where IssueDate between DATEADD('m', DATEDIFF('m', 0, DATE()) - 0 , 0) and DATEADD('m', DATEDIFF('m', 0, DATE()) + 1, - 1 ) group by usercategory
Data that i am holding in my MSACCESS Dbase -
Category1 9/7/2013 12:00:00 AM
Category1 9/8/2013 12:00:00 AM
Category2 10/8/2013 12:00:00 AM
so output should have only 2 records
but my query is giving no results
Here is the query I think you need. All the functions it uses are always available in Access SQL regardless of whether the query is run from within an Access session or from without (as in your c# situation).
The db engine will evaluate both those DateSerial expressions once, then use their results to filter the result set. This approach will be especially fast with an index on IssueDate.
SELECT
Count(usercategory) AS category_count,
usercategory
FROM user_category
WHERE
IssueDate >= DateSerial(Year(Date()), Month(Date()), 1)
AND IssueDate < DateSerial(Year(Date()), Month(Date()) + 1, 0)
GROUP BY usercategory;
Here is an Access Immediate window session which explains the logic for those DateSerial expressions ...
? Date()
9/6/2013
? Year(Date())
2013
? Month(Date())
9
' get the date for first of this month ...
? DateSerial(Year(Date()), Month(Date()), 1)
9/1/2013
' now get the date for the last of this month ...
? DateSerial(Year(Date()), Month(Date()) + 1, 0)
9/30/2013

Conversion failed when converting date and/or time from character string in gridview

In my GridView I can see my date column as mm/dd/yy normally but when I select a record and assign a string like so
GridViewRow row = GridView1.SelectedRow;
string sdate= row.Cells[2].Text; //Date is in Column 2
When I output this sdate string it returns: 1368309600000
And If I try to convert it, it doesn't work and I'm trying to select something from a SQL database and I get this error
Conversion failed when converting date and/or time from character string
EDIT: The part in the SQL statement for conversion is:
convert(datetime, '" + sdate +"', 101"+")
I suspect the problem is in the sdate itself but I'm not sure
Your date string appears to be expressed as the number of milliseconds since January 1, 1970, 00:00:00 GMT. The T-SQL CONVERT() function doesn't support this format. So, you could do a conversion to a C# DateTime like this...
DateTime date = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
.AddMilliseconds(Convert.ToDouble(sdate));
1368309600000 converts to 11/05/2013 22:00:00Z (this is UTC)
Then adjust for local time and reformat the date for your SQL string like this...
"convert(datetime, '" + date.ToLocalTime().ToString("MM/dd/yyyy") + "', 101)"
UpdateCommand="UPDATE [dbo].[ENTRY] set [_DATE] = CONVERT( date , #_DATE ,103) where [NO] = #NO "
important part here is 103 it is for format dd-mm-yyyy
check out your local format.
this problem only rises for people outside America.

compare between dates in .net

I want to compare between two dates.
From both the dates, I am fetching only date component using ToShortDateString(), as shown below. Now the problem is when I'm comparing the two dates. Its throwing error --
"Operator >= can't be applied to operands of type string and string."
DateTime srtdate = Convert.ToDateTime(allitem["StartDate"].Text.ToString());
DateTime srtdate = Convert.ToDateTime(allitem["StartDate"].Text.ToString());
(DateTime.Now.ToShortDateString() >= srtdate.ToShortDateString())
I need to compare date component only, NOT date and time together.
Please suggest what is the alternative way. Thanks
To JON:-
(I went tyhrough all what you explained and understood hopefully what the point actually you trying to make. Just to clarify more and make a last check I ll show an example.)
I have an web interface, where I give a start date and end date for a XYZ name (Note I can enter only date here, not time).
Start Date - 22-Feb-2012 AND End Date - 22-Feb-2012
Now in back end (code), if Start date and End date is same as Current date OR current date is in between start and end date, I want a ACTIVE flag set or else not. I give the condition as this:-
if ((DateTime.Today >= strdate.Date) && (DateTime.Today <= enddate.Date))
lblCondition.Text = "CHECKED";
Now when I debug the code,
Both DateTime.Today and strdate.Date gives the value as 2/22/2012 12:00:00 AM.
So, Jon my question is:- Would 'today' and 'date' work as per mentioned requirement, where only date component used. I hope it would.
Thanks a lot for all your explanantion before.
Why are you converting to a string representation at all? If you only want to compare the date parts to two DateTime values, just use the Date property on each of them:
if (x.Date >= y.Date)
And the Today property is equivalent to DateTime.Now.Date.
Both Date and Today strip off the time part, leaving a time of midnight. It's not ideal that you've still got a type which is capable of representing times, but that's just the way the DateTime API works :(
Note that you should usually avoid using DateTime.Now or DateTime.Today in web applications unless you're really comfortable with it using the system default time zone as the day boundary. The user's idea of "today" may not be the same as the server's.
You should avoid using string conversions unless your goal is really to get a text representation.
Of course another alternative would be to use the date/time library I'm building, Noda Time, where you could use a LocalDate type - obviously that makes it clearer that you're only interested in the date and not the time.
EDIT: As the OP seems unconvinced that Date really does ignore the time component, here's an example:
using System;
public class Test
{
static void Main()
{
// Two DateTime values with different times but
// on the same date
DateTime early = new DateTime(2012, 2, 22, 6, 0, 0);
DateTime late = new DateTime(2012, 2, 22, 18, 0, 0);
Console.WriteLine(early == late); // False
Console.WriteLine(early.Date == late.Date); // True
}
}
DateTime.Today >= strdate.Date
some thoughts
Think at the the following example: you need to compare the following numbers 1.5 and 2.5. These are represented in .Net as decimal, double or float, but let's use decimal. The greater one is 2.5
Let's say you need to compare the integral part of these numbers (1. and 2.). You will still use the decimal type to do the comparison.
Math.Truncate(x) ? Math.Truncate(y) // x = 1.5, y = 2.5
Same as for the DateTime. DateTime.Date will return the "integral" part of your date as Math.Truncate returns the integral part of a "real" number, but both will base on their original type.
hope this helps you.
using System;
public class Example
{
public static void Main()
{
DateTime date1 = new DateTime(2009, 8, 1, 0, 0, 0);
DateTime date2 = new DateTime(2009, 8, 1, 12, 0, 0);
int result = DateTime.Compare(date1, date2);
string relationship;
if (result < 0)
relationship = "is earlier than";
else if (result == 0)
relationship = "is the same time as";
else
relationship = "is later than";
Console.WriteLine("{0} {1} {2}", date1, relationship, date2);
}
}
// The example displays the following output:
// 8/1/2009 12:00:00 AM is earlier than 8/1/2009 12:00:00 PM

Categories