How do you name a something as approximately equal? Let's say I following have code:
private bool ErrorLogExists(LogEvent logEvent, DateTime filterStart)
{
    var startTimeFrom = logEvent.StartTime.TruncateMilliseconds();
    var startTimeTo = startTimeFrom.AddSeconds(1);

    return _existingErrorLogs.Any(x =&gt;
        x.Name == logEvent.Name &amp;&amp;
        x.EventDateTime &gt;= filterStart &amp;&amp;
        x.EventDateTime &gt;= startTimeFrom &amp;&amp;
        x.EventDateTime &lt;= startTimeTo);
}

The problem is that I think it is terrible.

I might just rename startTimeFrom and startTimeTo and remove :
x.EventDateTime &gt;= filterStart &amp;&amp;

as a cached view is already returned and it is no longer needed there.

I am tempted to write :
public static class DoubleExtensions
{
    internal const double AcceptableTolerance = .0005;
    public static bool IsApproximately(this double thisValue, double thatValue, double tolerance = AcceptableTolerance)
    {
        return Math.Abs(thisValue - thatValue) &lt;= tolerance;
    }
}
public static class DatetimeExtensions
{
    public static bool IsApproximately(this DateTime thisTime, DateTime thatTime, double toleranceInSeconds = DoubleExtensions.AcceptableTolerance)
    {
        var thisTimeInSeconds = thisTime.AsTotalSeconds();
        var thatTimeInSeconds = thatTime.AsTotalSeconds();

        return thisTimeInSeconds.IsApproximately(thatTimeInSeconds, toleranceInSeconds);
    }

    public static double AsTotalSeconds(this DateTime thisTime)
    {
        return (thisTime - DateTime.MinValue).TotalSeconds;
    }
}

so I could instead use
private bool ErrorLogExists(LogEvent logEvent, DateTime filterStart)
{
    return _existingErrorLogs.Any(x =&gt;
        x.Name == logEvent.Name &amp;&amp;
        x.EventDateTime.IsApproximately(logEvent.StartTime));
}


Reason why I would leave AsTotalSeconds as public, is that I would use it in tests. As in test tests, I already seem to have this partly supported. If I assume that I have:
var thisTimeInSeconds = thisTime.AsTotalSeconds();
var thatTimeInSeconds = thatTime.AsTotalSeconds();
var acceptableTolerance = .0005;

I could write :
Assert.That(thisTimeInSeconds, Is.EqualTo(thatTimeInSeconds).Within(acceptableTolerance);
thisTimeInSeconds.Should().BeApproximately(thatTimeInSeconds, acceptableTolerance);


The problem that I am facing is that
x.EventDateTime.IsApproximately(logEvent.StartTime))

has arguably even worse readability. People doing my code review might say :

&quot;WTF is this?&quot; / &quot;WTF is that?&quot; (I admit, I picked names so I could say that)
Why do we need IsApproximately?
Why is that an extension method and not a class method?
Is that DateTimes responsibility to know about this?
Is the logic change necessary?
Fine, you have DateTimeExtensions, why do you need DoubleExtensions?


My question is: How would you refactor this code?

Edit:
What I have currently:
    private bool ErrorLogExists(LogEvent logEvent)
    {
        var errorLogToleranceInMilliseconds = Properties.Settings.Default.ErrorLogToleranceInMilliseconds;
        var eventDateTimeFrom = logEvent.StartTime.AddMilliseconds(-errorLogToleranceInMilliseconds);
        var eventDateTimeTo = logEvent.StartTime.AddMilliseconds(errorLogToleranceInMilliseconds);

        return _existingErrorLogs.Any(x =&gt;
            x.Name == logEvent.Name &amp;&amp;
            x.EventDateTime &gt;= eventDateTimeFrom &amp;&amp;
            x.EventDateTime &lt;= eventDateTimeTo);
    }

... it's a bit better.
About your current implementation, you write:


  The problem is that I think it is terrible.


But then, you don't explain why. 

Then you go ahead and write much longer code, and a long list of objections.

In other words, maybe your original implementation is not so bad after all :)

The original code checks if there is any event that happened within the same second (more or less) as the reference event in the parameter (+ an additional date filter). The alternative implementation changes this logic to ±500 millis, which is different. Regardless of the logic you choose, the first option has some important benefits:


Simple
Efficient: sets constant values before a loop, rather than recalculate in every iteration


So I suggest to stick with that. Also remember Occam's razor.