List <DateTime>上的Any()方法不能按预期工作

Ami*_*mit 9 .net c# linq datetime

我在winforms中使用.net 4.6(这里的代码来自测试控制台应用程序)

有一点我有一个清单,DateTime我需要弄清楚这个清单是否包含具体的日期.

为此,我尝试使用Any()列表.即使列表确实包含所需日期,也只Any()返回false.

以下是示例代码,它也具有相同的行为.所以,如果我对这段代码有所了解,我想这对我的真实代码也有帮助.

List<DateTime> dateTimeList = new List<DateTime>();
DateTime dateNow = DateTime.Now;

DateTime date = new DateTime(dateNow.Year, dateNow.Month, dateNow.Day, dateNow.Hour, dateNow.Minute, 00);
date = date.AddMinutes(-10);
while (date < dateNow.AddMinutes(10))
{
    dateTimeList.Add(date);
    date = date.AddMinutes(1);
}

dateNow = dateNow.AddSeconds(-dateNow.Second);
dateNow = dateNow.AddMilliseconds(-dateNow.Millisecond);

foreach (DateTime dateInList in dateTimeList)
    Console.WriteLine("date list List:" + dateInList.ToString("ddMMyyyy hh:mm:ss:fffz") + " - VS - desired date:" + dateNow.ToString("ddMMyyyy hh:mm:ss:fffz"));

if (dateTimeList.Any(x => x == dateNow))
    Console.WriteLine("date found");
else
    Console.WriteLine("date Not found");

if (dateTimeList.Any(x => x.ToString("ddMMyyyy hh:mm:ss:fffz") == dateNow.ToString("ddMMyyyy hh:mm:ss:fffz")))
    Console.WriteLine("date string matched");
else
    Console.WriteLine("date string didn't match");
Run Code Online (Sandbox Code Playgroud)

输出:

在此输入图像描述

Eri*_*ert 43

在计算机编程中有一种说法"选择不破".这意味着当一些基本的,常用的,经过严格测试的软件似乎被打破时,问题在于你错误地诊断了问题,而不是工具被破坏了.

Any 工作得很好.

错误是您在一个地方正确地舍入日期而在另一个地方错误地舍入日期,并且错误的舍入日期不等于正确舍入的日期.使用Ticks日期中的属性来了解为什么您的一种舍入技术是好的,其中一种是完全错误的.


Sal*_*ari 23

TicksTimeOfDay项目在你的属性dateTimeList不等于TicksTimeOfDay性能你的dateNow,并且dateNow有一个比你更蜱dateTimeList.你需要添加这一行:

dateNow = new DateTime(dateNow.Year, dateNow.Month,
           dateNow.Day, dateNow.Hour, dateNow.Minute, 00);
Run Code Online (Sandbox Code Playgroud)

这将使TicksTimeOfDay你的性dateNow等于你已经添加到您的人dateTimeList.


Swe*_*per 10

找出发生这种情况的原因的关键是找出DateTime我们正在比较的两者之间的区别.

如果你打印出Ticks日期时间的属性,你会发现这样的事情:

636560893800004640
636560887800000000
636560893800004640
636560888400000000
636560893800004640
636560889000000000
636560893800004640
636560889600000000
636560893800004640
636560890200000000
636560893800004640
636560890800000000
636560893800004640
636560891400000000
636560893800004640
636560892000000000
636560893800004640
636560892600000000
636560893800004640
636560893200000000
636560893800004640
636560893800000000
636560893800004640
636560894400000000
636560893800004640
636560895000000000
636560893800004640
636560895600000000
636560893800004640
636560896200000000
636560893800004640
636560896800000000
636560893800004640
636560897400000000
636560893800004640
636560898000000000
636560893800004640
636560898600000000
636560893800004640
636560899200000000
636560893800004640
636560899800000000
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,这两行很可能是DateTime你认为相同的两行,但却不是:

636560893800004640
636560893800000000
Run Code Online (Sandbox Code Playgroud)

上面的dateNow那个是,下面的那个是列表中的那个.

看到不同?dateNow比列表中的刻度更多.

为什么是这样?

DateTime列表中的s date是通过使用带有6个参数的构造函数创建的.这会DateTime按照您的指定创建一个正确的.这意味着创建的实例不会为"余数"添加任何额外的刻度.我可以看到,当你改变你的时候dateNow,你试图删除你不关心的所有额外组件,比如秒和毫秒,但你忘记了滴答声.当你比较2 DateTime秒时,你实际上是在比较滴答.

new DateTime(1) == new DateTime(1)
true
new DateTime(1) == new DateTime(2)
false
Run Code Online (Sandbox Code Playgroud)

因此,您需要从中删除额外的刻度dateNow以获得所需的结果,或者再次使用6参数构造函数.

  • 在初始化并使用'date'的DateTime(长标记)构造函数之后从'dateNow'中删除秒和毫秒应该这样做 (2认同)