2

我有两个日期属性,它们与我从一个对象映射到另一个对象完全相同。如果我将它们进行如下比较,则返回 false:

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

他们都是{01/06/2011 15:44:32}

我不能使用DateTime.Compare,因为它们可以为空。比较可空日期的最佳方法是什么?

4

5 回答 5

7

检查这些日期的实际刻度,它们可能会有所不同。请注意,DateTime将 100 ns 间隔记录为其最小单位。格式化时不会显示这些DateTime

于 2013-02-07T14:50:07.067 回答
3

您可以使用该方法比较可空对象,包括可空日期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

正如其他答案所表明的那样,默认比较器适用于可为空的 DateTime 对象。您在评论中询问如何比较日期的舍入形式。你会想要这样的东西:

if (dt1.EqualsRounded(dt2))

以下是执行此操作所需的所有代码。它完全支持可空和不可空的日期时间。它实现了两者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

你不能在使用之前检查它们是否为空.Compare吗?

于 2013-02-07T14:49:45.543 回答