2

私には2つの日付プロパティがあり、それらは1つのオブジェクトから別のオブジェクトにマッピングしているのとまったく同じです。以下のように比較すると、falseが返されます。

if(obj1.d1 == obj2.d1)
{
}

どちらもです{01/06/2011 15:44:32}

DateTime.Comparenull許容型であるため使用できません。null許容の日付を比較するための最良の方法は何でしょうか?

4

5 に答える 5

7

これらの日付の実際のティックを確認してください。異なる場合があります。DateTime最小単位として 100 ns 間隔を記録することに注意してください。をフォーマットすると、これらは表示されませんDateTime

于 2013-02-07T14:50:07.067 に答える
3

メソッドを使用して、null 許容日付を含む null 許容オブジェクトを比較できますNullable.Compare<T>()

if(Nullable.Compare(obj1.d1, obj2.d1) == 0)
{
}
于 2014-11-11T21:18:28.723 に答える
1

それはうまくいくはずです、チェックしてください:

var now = DateTime.Now;
DateTime? d1 = now;
DateTime? d2 = now;

Console.WriteLine(d1 == d2); // Output: True

これらは実際にはまったく同じではないと思います。つまり、ミリ秒単位またはティック単位で異なります。

于 2013-02-07T14:50:26.100 に答える
1

他の回答が示しているように、デフォルトの比較子は、null 許容の DateTime オブジェクトに対して正常に機能します。丸められた形式の日付を比較する方法をコメントで尋ねました。次のようなものが必要です。

if (dt1.EqualsRounded(dt2))

以下は、これを行うために必要なすべてのコードです。null 許容および null 非許容の DateTime を完全にサポートします。IComparer<T>両方を実装してIEqualityComparer<T>いるため、リストをソートするときにもこれを使用できます (たとえば)。上記のような単純なケースには拡張メソッドがあり、異なる丸め間隔を提供するオーバーロードがあります。指定しない場合、デフォルトで最も近い整数秒に丸められます。楽しみ!

public static class DateTimeExtensions
{
    public static DateTime RoundToNearestInterval(this DateTime dateTime, TimeSpan interval)
    {
        // Adapted from http://stackoverflow.com/questions/1393696/c-rounding-datetime-objects

        // do the rounding
        var intervalTicks = interval.Ticks;
        var ticks = (dateTime.Ticks + (intervalTicks / 2) + 1) / intervalTicks;
        var totalTicks = ticks * intervalTicks;

        // make sure the result is not to low
        if (totalTicks < 0)
            totalTicks = 0;

        // make sure the result is not to high
        const long maxTicks = 0x2bca2875f4373fffL; // DateTime.MaxTicks
        if (totalTicks > maxTicks)
            totalTicks = maxTicks;

        // return the new date from the result
        return new DateTime(totalTicks, dateTime.Kind);
    }

    public static bool EqualsRounded(this DateTime x, DateTime y)
    {
        return x.EqualsRounded(y, TimeSpan.FromSeconds(1));
    }

    public static bool EqualsRounded(this DateTime x, DateTime y, TimeSpan interval)
    {
        var comparer = new RoundedDateTimeComparer(interval);
        return comparer.Equals(x, y);
    }

    public static bool EqualsRounded(this DateTime? x, DateTime? y)
    {
        return x.EqualsRounded(y, TimeSpan.FromSeconds(1));
    }

    public static bool EqualsRounded(this DateTime? x, DateTime? y, TimeSpan interval)
    {
        var comparer = new RoundedDateTimeComparer(interval);
        return comparer.Equals(x, y);
    }

    public static int CompareRounded(this DateTime x, DateTime y)
    {
        return x.CompareRounded(y, TimeSpan.FromSeconds(1));
    }

    public static int CompareRounded(this DateTime x, DateTime y, TimeSpan interval)
    {
        var comparer = new RoundedDateTimeComparer(interval);
        return comparer.Compare(x, y);
    }

    public static int CompareRounded(this DateTime? x, DateTime? y)
    {
        return x.CompareRounded(y, TimeSpan.FromSeconds(1));
    }

    public static int CompareRounded(this DateTime? x, DateTime? y, TimeSpan interval)
    {
        var comparer = new RoundedDateTimeComparer(interval);
        return comparer.Compare(x, y);
    }
}

public class RoundedDateTimeComparer : 
    IComparer<DateTime>, IComparer<DateTime?>,
    IEqualityComparer<DateTime>, IEqualityComparer<DateTime?>
{
    private readonly TimeSpan _interval;

    public RoundedDateTimeComparer(TimeSpan interval)
    {
        _interval = interval;
    }

    public int Compare(DateTime x, DateTime y)
    {
        var roundedX = x.RoundToNearestInterval(_interval);
        var roundedY = y.RoundToNearestInterval(_interval);
        return roundedX.CompareTo(roundedY);
    }

    public int Compare(DateTime? x, DateTime? y)
    {
        return x.HasValue && y.HasValue ? Compare(x.Value, y.Value) : (y.HasValue ? 1 : (x.HasValue ? -1 : 0));
    }

    public bool Equals(DateTime x, DateTime y)
    {
        var roundedX = x.RoundToNearestInterval(_interval);
        var roundedY = y.RoundToNearestInterval(_interval);
        return roundedX.Equals(roundedY);
    }

    public bool Equals(DateTime? x, DateTime? y)
    {
        return x.HasValue && y.HasValue ? Equals(x.Value, y.Value) : x.Equals(y);
    }

    public int GetHashCode(DateTime obj)
    {
        var rounded = obj.RoundToNearestInterval(_interval);
        return rounded.GetHashCode();
    }

    public int GetHashCode(DateTime? obj)
    {
        return obj.HasValue ? GetHashCode(obj.Value) : 0;
    }
}
于 2013-02-07T16:26:59.113 に答える
0

を使用する前に null かどうかを確認できません.Compareか?

于 2013-02-07T14:49:45.543 に答える