簡體   English   中英

我有一個條件,使用<運算符在C#中比較DateTime,即使它不應該返回false。 為什么?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM