Reputation: 9876
In my database the date is stored like datetime but when I want to perform a search/filtering I want it to be based only on the date ignoring the exact time. I spend a lot of time figuring out how to do it and finally I got a working solution on my own :
string val = rule.Data;
if (!string.IsNullOrEmpty(val))
{
switch (rule.Field)
{
case "Date": {
DateTime parsedDate = DateTime.ParseExact(
val,
"dd/MM/yyyy",
CultureInfo.InvariantCulture);
var pYear = parsedDate.Year;
var pMonth = parsedDate.Month;
var pDay = parsedDate.Day;
rows = rows.Where(o => o.Date >= parsedDate && o.Date <= new DateTime(pYear, pMonth, pDay, 12, 59, 40)); break;
}
}
}
This is working Ok. It needs a little change but I think I can use the code above. However today a college of mine pass me a solution which is from a previous project being developed here, and this solution is a lot shorter and I would prefer to use it if possble. It looks like this:
string val = rule.Data;
if (!string.IsNullOrEmpty(val))
{
switch (rule.Field)
{
case "Date": { rows = rows.Where(o => o.Date.ToString("dd/MM/yyyy") == val); break; }
}
}
The code doesn't break when I try this but it's not filtering data too. I always get empty result. I guess that o.Date.ToString("dd/MM/yyyy")
is where the problem lies. I don't know is it ok to use ToString()
like this for DateTime object. In the example I'm using ToString()
also get a format type like the one I'm providing here - ToString("dd/MM/yyyy")
- but in my case ToString()
is not overloaded anywhere. Is this a standard way to manipulate DateTime objects or I just can't find the place where ToStrin()
is predefined. And finally, can you provide me with a working example based on the code above.
Upvotes: 0
Views: 225
Reputation: 241693
You shouldn't have to use strings at all. If it is a datetime
(or similar) in the database, and a DateTime
in your c# code, then there is never a good reason to use a string as an intermediate step.
Also, you should pay close attention to the .Kind
property of your DateTime
values. And you should never be comparing local times against DateTime.Now
. If you do, you may introduce errors during daylight saving time transitions. Instead, you should use UTC DateTime
values, or use DateTimeOffset
values instead. Read more here.
Upvotes: 0
Reputation: 9725
Depending on what culture o.Date is, Try:
string val = rule.Data;
if (!string.IsNullOrEmpty(val))
{
switch (rule.Field)
{
case "Date":
{
rows = rows.Where(o => o.Date.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture) ==
DateTime.ParseExact(val,
"dd/MM/yyyy",
CultureInfo.InvariantCulture));
break;
}
}
}
Or you could set the culture of the current thread instead:
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
Edit: It should work if you avoid using strings:
e.g.
DateTime maxDate = new DateTime(2020, 11, 17);
if (DateTime.Now.Date > maxDate)
{
// this will just work regardless of setting culture
}
Upvotes: 1
Reputation: 30255
I think if you need to compare dates then you can just get a Date component of a DateTime and compare it to your predefined value. This should be faster as there won't be a need to transform date to string every time as well. So you can first get your reference value like that DateTime.ParseExact(value, "dd/MM/yyyy", CultureInfo.InvarianCulture)
. You can just use a constructor of a DateTime to compose it as well.
Upvotes: 0