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