![](/img/trans.png)
[英]Why does the C# 'is' operator give a correct result when comparing two boolean values and should I use it?
[英]I have a condition comparing DateTime in C# using the < operator and it return's false even if it should not. Why?
我在下面有此代碼,即使數據庫中的日期時間大於datetimenow,“ if((DateTime)DataReader [0]> DateTime.Now)”條件也會返回false。
我以前使用過此代碼,但它一直可以正常工作,所以我從未更改過任何東西。
那么問題是為什么條件返回假?
謝謝,
西蒙
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())
{
if ((DateTime)DataReader[0] > DateTime.Now)
active = true;
}
DataReader.Close();
if (active)
UpdateTime(sessionId);
Command.Dispose();
return active;
這是實際答案:
您不需要/不必/應該將DateTime與>,<,==或!=運算符進行比較。 相反,您可以使用DateTime類的Compare和CompareTo方法。
比較 :比較兩個DateTime實例,並返回一個整數,該整數指示第一個實例是早於,等於還是晚於第二個實例。
CompareTo :已重載。 將此實例的值與指定的DateTime值進行比較,並指示此實例是早於,等於還是晚於指定的DateTime值。
http://msdn.microsoft.com/en-us/library/system.datetime_members.aspx
首先,以這種方式使用DateTime是一個不好的做法。 您應該將DateTime.ToUniversalTime的值存儲在數據庫中,並使用DateTime.ToLocalTime方法將加載的DateTime轉換為本地時間。 同樣也不清楚從數據庫返回多少記錄,即您可以多次重寫活動狀態。 請向我們顯示(DateTime)DataReader [0]和DateTime.Now的值(包括DateTime.Kind屬性)
另外,程序邏輯看起來還很模糊-為什么將來會有注銷時間?
我建議使用一個變量並使用它與DateTime.Now進行比較
while (DataReader.Read())
{
// or use DateTime.Parse instead here
DateTime dbDate = (DateTime)DataReader[0];
if (dbDate > DateTime.Now)
active = true;
}
這將有助於簡化調試過程,並幫助您閱讀DataReader返回的內容。
附帶一提,我猜測數據庫包含空值。
我要做的第一件事是打印兩個時間值,這樣我就可以准確看到正在發生的事情。 如aku在評論中所述,請檢查時區差異。
編輯 :邏輯有意義嗎?
if ((DateTime)DataReader[0] > DateTime.Now)
日期/時間是注銷時間,對嗎? 因此,檢查是否為“如果注銷時間在將來,那么...”-還是我完全誤讀了此信息?
我猜,
這可能與while循環有關,您是否正在查看db中sessionID匹配的所有記錄?
為什么sessionID不是主鍵?
如果是,為什么要使用while循環?
嗯....您如何獲得比現在更大的“ LogoutDateTime”? 你有沒有彎曲的時間,讓你知道當你的用戶會退出?
如果您的數據庫字段中包含默認值(例如1990年1月1日),則可以解釋您的問題。 該字段或該字段應該為空,直到它們注銷,然后您應測試是否為空。
LogoutDateTime是會話的到期時間。 所以我要檢查的是會話是否過期。
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類型:未指定
DateTime.Now時間:2009-01-13 01:02:31類型:本地
主動:假
您的示例代碼將DateTimes與不同的DateTimeKind進行比較。 嘗試將它們轉換為相同類型,例如UTC。 這篇博客文章解釋了在比較中使用各種DateTimeKind的陷阱。
謝謝大家,我確實設置了一個要比較的變量,但沒有任何改變。 我還ser比較compare子,它沒有用。 當我減去刻度線時,它向我確認數據庫中的日期更大。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.