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.

有帮助吗?

解决方案

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
}

其他提示

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.

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top