C# MySQL LINQ DateTime conversion - c#

I'm trying to retrieve records from a mySQL DB using LINQ and C#.
The date in c# code is a string: 23-01-2010
I need to convert this to DateTime format as 2010-01-23 (mySQL default DateTime format), otherwise the query does not return any records, at present it errors saying a string cannot be matched against a DateTime (row.DateOfIssue)
If I convert the string to DateTime (C#), then it is not in the mySQL DateTime format of yyyy-MM-dd
String endDate = "23-01-2010";
var query = (from row in uow.UserPersonalLicenseDetails
where (endDate >= row.DateOfIssue && endDate <= row.DateOfExpiry)
select row)
This is such a standard query it seems mad that it is so hard to do in LINQ.
It seems putting any method like CompareTo etc in the where clause causes an error of "Search for a class that works in this scenario"
I'm now wondering if the best line of attack might be to write a stored procedure in the database. This could then take the C# datetime as a parameter, convert it to mySQL format and then run the required query.....
Any thoughts?

Make it a DateTime - so
var myDate = DateTime.Parse(endDate);
Then
myDate.ToString("yyyy-MM-dd");
---------- or this:
var myDate = DateTime.Parse(endDate);
var query = (from row in uow.UserPersonalLicenseDetails
where ((myDate.CompareTo(row.DateOfIssue)>=0 && (myDate.CompareTo(row.DateOfExpiry)<=0)
select row

Just convert your date string to DateTime and then in the LINQ convert the string to DateTime that's coming back in order to do the comparison. I've used ParseExact because we need to make sure that we are parsing to the exact format that MySQL stores the date in, which is yyyy-MM-dd hh:mm.
Something like:
var endDate = DateTime.Parse("23-10-2010").ToString("yyyy-MM-dd hh:mm");
var formattedEndDate = DateTime.Parse(endDate);
//you could cut that to one line by putting the date in said format in the first place
var query = (from row in uow.UserPersonalLicenseDetails
where formattedEndDate >= row.DateOfIssue
&& formattedEndDate <= row.DateOfExpiry
select row)

Ok, problem was that the Table had the field defined as DATE rather than DATETIME so no match was being made.
Used DateTime.Date and the match was made.

Related

How to take a varchar field and compare as date in C# using RowFilter

I have a field in my SQL table
`OurDate (varchar(250), null)`
//sample dates
// 01/18/2018
// 05/12/2016
// 03/05/2012
I am trying to compare the table data between two dates in that field column using RowFilter:
string fromDate = "{OurDate Sql column value from dropdown list}"; //01/18/2018
string toDate = "{OurDate Sql column value from dropdown list}"; //01/18/2018 (could be different, if someone doesn't want same day)
dataTable.DefaultView.RowFilter = string.Format("(CONVERT({0}, 'System.DateTime') >= #" + Convert.ToDateTime(fromDate) + "# And {0} <= #" + Convert.ToDateTime(toDate) + "# )", "OurDate");
I get this error:
String was not recognized as a valid DateTime.
Can someone please assist me in resolving this issue.
First you should identify what causes the Conversion issue.
Is it the CONVERT expression or the values used for filtering.
You can do this by splitting up your code and adding an expression column just for the conversion like this:
dataTable.Columns.Add("TEST", typeof(DateTime), "CONVERT(OurDate, 'System.DateTime')");
If this line causes the error - it means that the problem is converting the data. DataExpression's CONVERT function should be based on the dataTable.Locale (which defaults to CultureInfo.CurrentCulture) property.
If your data is indeed always in "MM/dd/yyyy" format setting this to
dataTable.Locale = new CultureInfo("en-US");
Should solve the problem - If the data in the table is in an inconsistent format - you will not be able to solve this using RowFilter/DataExpressions
At this point you will notice that your second filter condition is missing the CONVERT entirely.
In fact this entire convert step is superficial if all of your data is in the correct format - if RowFilter detects its correct format for datetime - it will apply this conversion automatically to your column.
That being said .RowFilter only accepts dates in the following formats
American "MM/dd/yyyy" and "yyyy/MM/dd" (which I guess is considered Invariant here?)
If your local format is not one of these calling Convert.ToDateTime(fromDate) will cause a failure to convert.
Since your strings are already in one of the accepted formats - calling this should just be a pointless round trip anyway.
TL;DR: assuming all your formats are correct this should work:
dataTable.DefaultView.RowFilter = $"OurDate >= #{fromDate}# And OurDate <= #{toDate}#";
If your rows have different formats you'll need something with more control - I'd recommend LINQ to DataSet as the easiest way out since you'll be able to return DataViews/DataTables with it.
Try this instead of ConvertTo:
DateTime.ParseExact(myStr, "MM/dd/yyyy", CultureInfo.InvariantCulture);
I found it here How convert string to Datetime by a format? and changed the syntax a little to fit your db values' format.
Also you can use like that;
i think this way more readable more than rowfilter;
static void Main(string[] args)
{
string givenDateString = "01/26/2018";
DateTime convertedDateFromString = new DateTime();
DateTime.TryParse(givenDateString, out convertedDateFromString);
DataTable dt = new DataTable();
dt.Columns.Add("OurDate", typeof(System.DateTime));
DataRow dR = dt.NewRow();
dR["OurDate"] = DateTime.Now;
dt.Rows.Add(dR);
//way 1
var result = from d in dt.AsEnumerable().ToList()
where d.Field<DateTime>("OurDate").Date == convertedDateFromString.Date
select d;
Console.WriteLine(result.FirstOrDefault()["OurDate"].ToString());
//way 2
var result2 = from d in dt.AsEnumerable()
where d.Field<DateTime>("OurDate").Date == convertedDateFromString.Date
select d;
//result.FirstOrDefault<DataRow>[""];
Console.WriteLine(result2.FirstOrDefault<DataRow>()["OurDate"].ToString());
}

Comparing Dates in Database to DateTime.Now

I have database table in which the dates are stored in the following format
I need to compare the current system date with the date stored in the db.
I get the system date using DateTime.Now
But since these 2 dates are in different formatting... how can i convert and compare so that i can select only the required values.
Try this:
Get only date from system datetime and compare with database date column value
You also get only date from database
//Database
SELECT CONVERT(date, Transaction_Date) FROM TableName
//Application
if(DateTime.Now.Date==databasedate)
If your database column is datetime format then after pull out data and store in a datetime type variable both will be a C# DateTime instance, So you can compare them without any format specification
DateTime date1 = DateTimeFromDb;
DateTime date2 = DateTime.Now;
int result = DateTime.Compare(date1, date2);
if(result == 0 )
Console.WriteLine("Same")

How to compare the database field and datetime in asp.net

NET and I working on a program where I take some data from database and try to compare with the DateTime field.
For Example I have certain documents in the SEIBEL database and I want expiration date of those documents and compare the with current date and time and fire message accordingly. But somehow I an unable to compare them.
This is the sql query in asp.net that I am running
private static readonly string GET_PROVIDER_DOCUMENTS = #"
select sc.row_id,
doc.created as created_date,
doc.attrib_04 as document_type,
doc.attrib_47 as exipration_date,
att.row_id as document_row_id,
att.file_name || '.' || att.file_ext as file_name
from siebel.s_org_ext sc
join siebel.s_org_ext_xm doc
on doc.par_row_id = sc.row_id
and doc.type = 'SCLicenseInfo'
and doc.attrib_35 = 'Expiration Date'
and doc.attrib_04 in ('Certificate of Insurance', 'Master Service Agreement')
left join siebel.s_accnt_att att on att.comments = doc.row_id
where sc.row_id = :sc_row_id
";
and this where I trying to get expiration date from database
ExpirationDate = ConvertExpirationDate(dr["exipration_date"].ToString()),
If anybody has any idea about it it would great. Thanks in advance
Have you looked at the TryParse method on a DateTime object?
https://msdn.microsoft.com/en-us/library/system.datetime.tryparse(v=vs.110).aspx
May be suitable for your needs though I believe it will depend on the format your date is stored in.
Assuming you are successfully getting the datetime from the datebase and storing it as a string called ExpirationDate:
DateTime date1 = Convert.ToDateTime(ExpirationDate);
Datetime date2 = new Datetime(---)//desired date to compare with.
if(DateTime.Compare(date1,date2)==0)
{
// They're equal.
}
else
{
// Not equal.
}
Converting:
https://msdn.microsoft.com/en-us/library/system.convert.todatetime(v=vs.110).aspx
Comparing:
https://msdn.microsoft.com/en-us/library/system.datetime.compare(v=vs.110).aspx
Alternatively you could compare the day / month / year components of the date like this :
DateTime today = DateTime.Today;
if(ExpirationDate.Year == today.Year &&
ExpirationDate.Month = today.Month && ExpirationDate.Day = today.Day )

UTC in DB confusion when querying in linq from Web API server

I can really use some help wrapping my head around a problem I'm having querying data according to a SQL Date field.
I am storing the Date in UTC format using the following code:
objFitCalendarDto.Day = objFitCalendarDto.Day.ToUniversalTime();
That line assigns the date to the model that is inserted into the db through Entity Framework.
Now, my query is supposed to retrieve a row based on a date. So, I should be able to get the row for today, tomorrow, yesterday, and so on.
To do this, I'm using the method to search between two dates, a start date and an end date as follows:
DateTime dayBegin = DateTime.Today.Date.AddDays(dayOffset);
DateTime dayEnd = DateTime.Today.Date.AddDays(dayOffset + 1);
The purpose of dayOffset is to specify which day. If Offset is 0, then I am searching for Today. If dayOffset is 1, then I am searching for rows with tomorrow's date.
Now, since I stored the data originally in UTC, I am assuming that I must search for it in UTC as well. So before executing my query, I convert the dates to UTC like so:
dayBegin = TimeZoneInfo.ConvertTimeToUtc(dayBegin);
dayEnd = TimeZoneInfo.ConvertTimeToUtc(dayEnd);
Then I execute my query like so:
var query = (from f in Db.FitCalendars
where f.FitProgramId == programId &&
f.DayAsDate >= dayBegin && f.DayAsDate < dayEnd
select f);
problem is, it doesn't work. I have a row with the date, "2016-01-26" when I look at it in SQL Manager. However, it only returns from a query on yesterday's date. Today is 2016-01-26, by the way. Clearly I'm not getting this UTC concept. Can anyone see what I'm doing wrong here? I was assuming that if I stored everything as UTC and then before querying I converted my dates for the query to UTC, that everything should work.
UPDATE
Let's try like this:
As soon as you are storing only date part (SQL 'date' type), you
need to compare also only dates.
Instead of
DateTime dayBegin = DateTime.Today.Date.AddDays(dayOffset);
dayBegin = TimeZoneInfo.ConvertTimeToUtc(dayBegin);
let's just do
DateTime dayBegin = DateTime.UtcNow.Date.AddDays(dayOffset);
dayBegin in that case will be date with time anyway (time is 12:00:00 AM). It means, we need to truncate it with DbFunctions. We need equality check here.
var query = (from f in Db.FitCalendars
where f.FitProgramId == programId &&
f.DayAsDate == DbFunctions.TruncateTime(dayBegin)
select f);
END OF UPDATE
I believe that problem is that you comparing dates with times. In your case you need to compare only dates, as far as I understand. As a solution - use DbFunctions TruncateTime function. It can be used within linq queries - like in your code.
https://msdn.microsoft.com/en-us/library/system.data.entity.dbfunctions.truncatetime(v=vs.113).aspx
So, complete solution would be
var query = (from f in Db.FitCalendars
where f.FitProgramId == programId &&
DbFunctions.TruncateTime(f.DayAsDate) >= DbFunctions.TruncateTime(dayBegin) && DbFunctions.TruncateTime(f.DayAsDate) < DbFunctions.TruncateTime(dayEnd)
select f);

Trouble bringing in a string with d-MMM-yy format parse.exact to date but keeping date format and date type for sorting

As the title said I am bringing in a date string from a datatable with the format of "d-MMM-yy" or 27-AUG-06.
I need to convert it to a date type for sorting, but I need to keep the same format for display.
NOTE: I am using C#, .Net 2.0, and I am retyping this code so bear with me on typos
System.Globalization.DateTimeFormatInfo dtfi;
dtfi = new System.Globalization.DateTimeFormatInfo();
dtfi.ShortDatePattern = "d-MMM-yy";
dtfi.DateSeperator = "-";
//this is in a for loop with rowCnt being the row index/counter: loop and datatable is working fine.
//"newRow" represents a DataRow in the new table.
// the table [row] [column] is bringing in the string date like "27-AUG-06"
//colXDate IS RECORDED AS {8/27/2006 12:00:00 AM}
DateTime colXDate = DateTime.ParseExact(inputDataTable.Rows[rowCnt]["colX"].ToString(), "d-MMM-yy", System.Globalization.CultureInfo.InvariantCulture);
//#### THIS NEXT LINE IS WHERE IT GIVES ME AN ERROR "String was not recognized as valid datetime."
newRow["colX"] = Convert.ToDateTime(colXDate.ToString(), dtfi);
Since you already have colXDate as a DateTime, you don't need to convert it to a string and then back into a datetime.
Instead, try this:
newRow["colX"] = colXDate.ToString("d-MMM-yy");
Your line fails because ToString() will output the date in the format defined in the current culture and you are trying to convert it back to a date using your custom date format.
You need to set it to colXDate.ToString("d-MMM-yy").
SCENARIO: I am passing a datatable back as a DataGrids datasource. I am passing in a string field that is a date. I want to convert it to a date so that I can sort by it but I also want to maintain the same format that it was on the string that came in.
ISSUE: From some of my research it seems that the DateTime type is exactly that a datatype in whatever datatable that you put it in and is not formatable. So even though I bring in an unormal string date and convert it to a datetime via the DateTime.ParseExact, when I put it into my datetime field and try to format it (newRow["colX"] = colXDate.ToString("d-MMM-yy"); //as Scott had above) it still goes in as a set datetime format with hours...etc.
SOLUTION: So I resolved this by smoke and mirrors. I put 2 columns in the datatable, the first being the string format display date and the second the datetime type. On ItemDataBound I hid the datetime column (e.Item.Cells[5].Visible = false;) and then on the sort event I test for string date column (e.SortExpression == "colX") and if it is true I sort by the hidden datetime column.

Categories