DataTable过滤器表达式,包含DateTime和运算符不正确的运算符问题

时间:2009-12-21 12:25:13

标签: c# ado.net

我有以下代码:


            DataTable t = new DataTable();
            t.Locale = CultureInfo.InvariantCulture;
            t.Columns.Add("Date", typeof(DateTime));

            DateTime today = DateTime.Now;
            DateTime yesterday = today.AddDays(-1);
            DateTime tomorow = today.AddDays(1);

            t.Rows.Add(yesterday);
            t.Rows.Add(today);
            t.Rows.Add(tomorow);

            string filter = string.Format(CultureInfo.InvariantCulture,
                "Date >= #{0}# AND Date <= #{1}#", yesterday, tomorow);

            t.DefaultView.RowFilter = filter;

            foreach (DataRowView v in t.DefaultView)
                Console.WriteLine(v["date"]);

我希望过滤的t.DefaultView现在包含所有三个“天”。但由于某种原因,该范围的最后日期不包括在内。 <=类型的DateTime运算符似乎与<类似。

问题出在哪里?那是一个错误吗?有什么建议如何克服这个?

更新 得到了关于DateTime类型和比较运算符的一些回复。谢谢。 但现在我想引导注意filter expression。 好吧,说我有一个完整的循环:


foreach (DataRow r in t.Rows)
{
  DateTime date = (DateTime)r["Date"];
  if (yesterday <= date && date <= tomorow)
      Console.WriteLine(date);
}

此循环应显示与

相同的结果

foreach (DataRowView v in t.DefaultView)
  Console.WriteLine(v["date"]);

从上一个例子中,是吗?没有!这里<=正如我期待的那样工作,结果全部都是三天。为什么呢?

更新#2:解决方案。 正如乔所指出的那样 - 这个问题只有几分之一秒。 如果我使用往返日期/时间模式格式化上限和下限(以保留一秒的分数) - 一切正常:



string filter = string.Format(CultureInfo.InvariantCulture,
                "Date >= '{0}' AND Date <= '{1}'",
                yesterday.ToString("o", CultureInfo.InvariantCulture),
                tomorow.ToString("o", CultureInfo.InvariantCulture));

3 个答案:

答案 0 :(得分:2)

日期比较需要考虑时间。因此,例如,“今天中午”大于“今天”。如果您使用DateTime.Now,则包含时间。因此,如果DateTime.Now是“今天中午”,则tomorrow = today.AddDays(1)小于“明天下午3点”......所以你需要忽略日期的时间部分。您可以通过无需时间格式化日期来实现。此外,如果你想检查一个日期是“比明天更少或更多”(无论时间如何),检查它是否“严格地比后天”:

string filter = string.Format(CultureInfo.InvariantCulture,
                "Date >= #{0:MM/dd/yyyy}# AND Date < #{1:MM/dd/yyyy}#",
                yesterday,
                tomorrow.AddDays(1));

答案 1 :(得分:1)

尝试

DateTime today = DateTime.Today;

如果不解决,请检查您的日期字段是否也包含时间。这就是你的问题。

更新:您的第二条评论。

与DateTime.Now进行比较时,例如日期&lt; = 21.12.2009 14:35:35,它将在14:35之前完成,并将忽略后面的行。希望这会对你有所帮助。

请参阅以下文章以获得更多想法

http://dotnetguts.blogspot.com/2007/06/understanding-datetime-and-timespan-in.html

答案 2 :(得分:1)

您在更新中发布的代码与行筛选器不同。 您的行过滤器使用当前区域性的常规格式来格式化日期。这可能不包括一秒的分数 - 因此除非您碰巧在第二个边界上调用DateTime.Now,否则您的tomorrow值将超出过滤器指定范围的某些时间。

即。如果您的tomorrow值是'2009-12-23 01:02:03.456',那么您的行过滤器只会获取值,包括'2009-12-23 01:02:03',几个分数在明天指定的值之前的第二个。

如果您只想比较日期,则应使用DateTime.Date截断日期中的时间组件(并使用DateTime.Today而不是DateTime.Now作为当前日期)。