C# 我有一个条件,使用<;运算符及其返回值';即使不应该,它也是假的。为什么?

C# 我有一个条件,使用<;运算符及其返回值';即使不应该,它也是假的。为什么?,c#,C#,下面是我的代码,“if((DateTime)DataReader[0]>DateTime.Now)”条件返回false,即使数据库中的DateTime大于datetimenow 我以前使用过这段代码,但它一直在工作,我从未改变过任何东西 所以问题是为什么条件返回false 谢谢 西蒙 我建议使用一个变量&用它来与DateTime进行比较 while (DataReader.Read()) { // or use DateTime.Parse instead here DateT

下面是我的代码,“if((DateTime)DataReader[0]>DateTime.Now)”条件返回false,即使数据库中的DateTime大于datetimenow

我以前使用过这段代码,但它一直在工作,我从未改变过任何东西

所以问题是为什么条件返回false

谢谢

西蒙


我建议使用一个变量&用它来与DateTime进行比较


while (DataReader.Read())
{
    // or use DateTime.Parse instead here
    DateTime dbDate = (DateTime)DataReader[0];
    if (dbDate > DateTime.Now)
        active = true;
}


这将有助于更轻松地调试,并帮助您读取DataReader返回的内容。
另一方面,我猜测DB包含空值。

我要做的第一件事是打印两个时间值,以便能够准确地看到发生了什么。正如aku在评论中提到的,检查时区差异

编辑:逻辑合理吗

if ((DateTime)DataReader[0] > DateTime.Now)

日期/时间是注销时间,对吗?所以这是检查“如果注销时间在未来,那么…”-或者我完全误解了这一点?

谢谢各位,我设置了一个变量进行比较,没有任何更改。我还想比较一下滴答声,但没有效果。当我减去刻度时,它向我证实了数据库中的日期更大。

我猜

这可能与while循环有关,您是否正在查看数据库中sessionID匹配的所有记录

为什么sessionID不是主键


如果是,为什么使用while循环

嗯……您如何获得比现在更大的“注销日期时间”?您是否已调整时间,以便知道用户何时将要注销


如果您的数据库字段中有一个默认值(例如1/1/1990),那么这可以解释您的问题。在他们注销之前,该字段或该字段都应为null,您应该测试是否为null。

首先,以这种方式使用DateTime是一种不好的做法。您应该在数据库中存储DateTime.ToUniversalTime的值,并使用DateTime.ToLocalTime方法将加载的DateTime转换为本地时间。此外,还不清楚数据库将返回多少记录,即您可以多次重写活动记录。只需向我们显示(DateTime)DataReader[0]和DateTime.Now的值(包括DateTime.Kind属性)


此外,程序逻辑看起来不清楚-为什么注销时间在将来?

注销日期时间是会话的到期时间。所以我检查的是会话是否过期

sessionID是主键,因此where子句不能返回超过1个结果

为什么我要用一段时间?因为这是我知道的使用SqlDataReader的方式。还有更好的办法吗?请开导我

表创建脚本:

CREATE TABLE [dbo].[Sessions](
    [SessionID] [int] IDENTITY(1,1) NOT NULL,
    [UserId] [int] NOT NULL,
    [LoginDateTime] [datetime2](7) NOT NULL,
    [LogoutDateTime] [datetime2](7) NOT NULL,
    [Culture] [nvarchar](5) NOT NULL
) ON [PRIMARY]
与日志相同的方法:

    public static Boolean GetActive(Int32 sessionId)
    {
        Boolean active = false;
        SqlConnectionUniqueInstance.Instance.Open();
        SqlCommand Command = SqlConnectionUniqueInstance.Instance.Connection.CreateCommand();
        Command.CommandText = String.Format(@"SELECT [LogoutDateTime] FROM [dbo].[sessions] WHERE [sessionID] = {0}", sessionId.ToString());
        SqlDataReader DataReader = Command.ExecuteReader();
        while (DataReader.Read())
        {
            System.IO.File.AppendAllText("C:\\Log.txt", "DataBase Time    :" + ((DateTime)DataReader[0]).ToString() + " Kind:" + ((DateTime)DataReader[0]).Kind.ToString() + "\r\n");
            System.IO.File.AppendAllText("C:\\Log.txt", "DateTime.Now Time:" + DateTime.Now.ToString() + " Kind:" + DateTime.Now.Kind.ToString() + "\r\n");

            if ((DateTime)DataReader[0] > DateTime.Now)
                active = true;
            System.IO.File.AppendAllText("C:\\Log.txt", "active:" + active.ToString() + "\r\n");
        }
        DataReader.Close();
        if (active)
            UpdateTime(sessionId);
        Command.Dispose();
        return active;
    }
日志:

数据库时间:2009-01-13 01:32:28种类:未指定

日期时间。现在时间:2009-01-13 01:02:31种类:本地


active:False

这是实际答案:


您不需要/已经/应该将DateTime与>,示例代码是将DateTimes与不同的DateTimeKind进行比较。尝试将它们转换为相同的类型,例如UTC。这解释了在比较中不同DateTimeKind的陷阱。

DataReader[0]和DateTime的值是多少。现在调试器显示了什么?时区呢?另一方面,您不需要对String.Format方法的参数调用ToString()。当读卡器的行数用完时,while循环将退出。当没有更多行可读取时,Read()返回false。看起来他的“active”变量只是跟踪任何行是否满足条件。我同意他应该将其移动到while子句本身,或者至少在if语句中插入一个“break”。
    public static Boolean GetActive(Int32 sessionId)
    {
        Boolean active = false;
        SqlConnectionUniqueInstance.Instance.Open();
        SqlCommand Command = SqlConnectionUniqueInstance.Instance.Connection.CreateCommand();
        Command.CommandText = String.Format(@"SELECT [LogoutDateTime] FROM [dbo].[sessions] WHERE [sessionID] = {0}", sessionId.ToString());
        SqlDataReader DataReader = Command.ExecuteReader();
        while (DataReader.Read())
        {
            System.IO.File.AppendAllText("C:\\Log.txt", "DataBase Time    :" + ((DateTime)DataReader[0]).ToString() + " Kind:" + ((DateTime)DataReader[0]).Kind.ToString() + "\r\n");
            System.IO.File.AppendAllText("C:\\Log.txt", "DateTime.Now Time:" + DateTime.Now.ToString() + " Kind:" + DateTime.Now.Kind.ToString() + "\r\n");

            if ((DateTime)DataReader[0] > DateTime.Now)
                active = true;
            System.IO.File.AppendAllText("C:\\Log.txt", "active:" + active.ToString() + "\r\n");
        }
        DataReader.Close();
        if (active)
            UpdateTime(sessionId);
        Command.Dispose();
        return active;
    }