为什么在测试 DateTime 相等性时此单元测试会失败?

发布于 2024-07-10 10:14:43 字数 672 浏览 10 评论 0原文

在 .NET 3.5 上使用 NUnit 2.2,使用 DateTime.Equals 时以下测试失败。 为什么?

[TestFixture]
public class AttributeValueModelTest
{
    public class HasDate
    {
        public DateTime? DateValue
        {
            get
            {
                DateTime value;
                return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
            }
        }

        public object ObjectValue { get; set; }
    }

    [Test]
    public void TwoDates()
    {
        DateTime actual = DateTime.Now;
        var date = new HasDate {ObjectValue = actual};
        Assert.IsTrue(date.DateValue.Value.Equals(actual));
    }
}

Using NUnit 2.2 on .NET 3.5, the following test fails when using DateTime.Equals. Why?

[TestFixture]
public class AttributeValueModelTest
{
    public class HasDate
    {
        public DateTime? DateValue
        {
            get
            {
                DateTime value;
                return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
            }
        }

        public object ObjectValue { get; set; }
    }

    [Test]
    public void TwoDates()
    {
        DateTime actual = DateTime.Now;
        var date = new HasDate {ObjectValue = actual};
        Assert.IsTrue(date.DateValue.Value.Equals(actual));
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

审判长 2024-07-17 10:14:43

日期不相等。 TryParse 会丢弃一些刻度。 比较刻度值。

对于一次测试运行:

Console.WriteLine(date.DateValue.Value.Ticks);
Console.WriteLine(actual.Ticks);

产量:

633646934930000000
633646934936763185

The dates aren't equal. TryParse drops some ticks. Compare the Tick values.

For one test run:

Console.WriteLine(date.DateValue.Value.Ticks);
Console.WriteLine(actual.Ticks);

Yields:

633646934930000000
633646934936763185
鲜血染红嫁衣 2024-07-17 10:14:43

问题实际上不是 TryParse,而是 ToString()。

DateTime 对象的起始精度(如果不是准确的话)低至百万分之一秒。 ToString() 将其转换为字符串,精度仅为秒。

TryParse 正在尽其所能。

如果您添加格式说明符(沿着 "yyyy-MM-dd HH:mm:ss.ffffff" 行),它应该可以工作。

The problem isn't really TryParse, but actually ToString().

A DateTime object starts with precision (if not accuracy) down to millionth of seconds. ToString() convertsit into a string, with precision only to a second.

TryParse is doing the best it can with what it is given.

If you add a format specifier (along the lines of "yyyy-MM-dd HH:mm:ss.ffffff"), it should work.

我纯我任性 2024-07-17 10:14:43

要指定包含所有精度的格式,可以使用 String.Format() 方法。 詹姆斯给出的例子如下:

String.Format("{0:yyyy-MM-dd HH:mm:ss.ffffff}", ObjectValue);

我不知道当你传递一个不是日期的东西时它会做什么。

也许更简单的方法是当您已经有了日期对象时添加一个特殊情况:

    public DateTime? DateValue
    {
        get
        {
            DateTime value = ObjectValue as DateTime;
            if (value != null) return value;
            return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
        }
    }

To specify a format that includes all the precision, you can use the String.Format() method. The example that James gives would look like this:

String.Format("{0:yyyy-MM-dd HH:mm:ss.ffffff}", ObjectValue);

I don't know what that will do when you pass it something that's not a date.

Perhaps a simpler approach is to add a special case when you've already got a date object:

    public DateTime? DateValue
    {
        get
        {
            DateTime value = ObjectValue as DateTime;
            if (value != null) return value;
            return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
        }
    }
坏尐絯 2024-07-17 10:14:43

public DateTime? DateValue
        {
            get
            {
                DateTime value;
                bool isDate = DateTime.TryParse(ObjectValue.ToString(), out value); 
                return isDate ? new DateTime?(value) : new DateTime?();
            }
        }


public DateTime? DateValue
        {
            get
            {
                DateTime value;
                bool isDate = DateTime.TryParse(ObjectValue.ToString(), out value); 
                return isDate ? new DateTime?(value) : new DateTime?();
            }
        }

无人问我粥可暖 2024-07-17 10:14:43

我不知道这在 .NET 中是否相同,但在 Java 中, equals 通常只会比较实例是否相同,而不是值是否相同。 相反,您想使用compareTo。

I don't know if this is the same in .NET, but in Java the equals often will only compare if the instances are the same, not if the values are the same. You'd instead want to use compareTo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文