简体   繁体   中英

DateTime comparison with formatting in LINQ

I am trying to write a simple LINQ query in which DateTime is compared to get the results. My requirement is that the DateTime has to be compared only till milliseconds and hence I have to apply formatter. The query is as follows

var availableValues = from value in AvailableValues
                      where DateTime.Compare(DateTime.ParseExact(value.Time.ToString("dd/MM/yyyy HH:mm:ss.fff"), "dd/MM/yyyy HH:mm:ss.fff", System.Globalization.CultureInfo.CurrentCulture),
                      DateTime.ParseExact(currentTime.ToString("dd/MM/yyyy HH:mm:ss.fff"), "dd/MM/yyyy HH:mm:ss.fff", System.Globalization.CultureInfo.CurrentCulture)) == 0
                      select value;

AvailableValues is huge collection and the above query is causing a perfomance hit.

It would be of great help if someone could suggest me a better way to achieve the expected result.

  1. Cache the value for the currentTime to avoid recalculating it for every comparison

  2. As far as I understand, you only want to compare including whole milliseconds (no fractions, no ticks). So you can create new DateTime values with only whole ms like that (if your query provider allows that):

     DateTime current = new DateTime( currentTime.Year, currentTime.Month, currentTime.Day, currenTime.Hour, currentTime.Minute, currentTime.Second, currentTime.Kind). AddMilliseconds(currentTime.Millisecond); var availableValues = from value in AvailableValues where currentTime == new DateTime( value.Time.Year, value.Time.Month, value.Time.Day, value.Time.Hour, value.Time.Minute, value.Time.Second, value.Time.Kind). AddMilliseconds(value.Time.Millisecond) select value; 

This should be a lot faster than converting your DateTime s to string and back again.

My requirement is that the DateTime has to be compared only till milliseconds and hence I have to apply formatter.

Nope, you don't have to apply a formatter. Simply create a new date with an empty millisecond component. Instead of

DateTime.Compare(date1, date2)

use

DateTime.Compare(DropMilliseconds(date1), DropMilliseconds(date2))

or, since your are only interested in equality (not in the additional information that DateTime.Compare will give you):

DropMilliseconds(date1) == DropMilliseconds(date2)

with DropMilliseconds defined as follows (or any alternative implementation ):

private static DateTime DropMilliseconds(DateTime dtm)
{
    return new DateTime(dtm.Year, dtm.Month, dtm.Day, 
                        dtm.Hour, dtm.Minute, dtm.Second, 
                        dtm.Kind);
}

If you are worried about the method call overhead, you can tell the compiler to aggressively inline it .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM