我有一个条件比较 C# 中的 DateTime 使用 < 运算符,即使它不应该返回 false。为什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/434367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 03:14:40  来源:igfitidea点击:

I have a condition comparing DateTime in C# using the < operator and it return's false even if it should not. Why?

c#

提问by

I have this code below and the "if ((DateTime)DataReader[0] > DateTime.Now)" condition returns false even if the datetime in the database is greater than the datetimenow.

我在下面有这个代码,即使数据库中的日期时间大于 datetimenow,“if ((DateTime)DataReader[0] > DateTime.Now)”条件也会返回 false。

I used this code before and it use to work I never changed any thing.

我以前使用过这段代码,它用来工作我从未改变过任何东西。

So the question is why does the condition return false?

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

Thanks,

谢谢,

Simon

西蒙

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;

采纳答案by aku

This is the actual answer:

这是实际的答案:

You do not need/have/should to compare DateTime with >, <, == or != operators. Instead you can use the Compare and CompareTo methods of the DateTime class.

您不需要/拥有/应该将 DateTime 与 >、<、== 或 != 运算符进行比较。相反,您可以使用 DateTime 类的 Compare 和 CompareTo 方法。

Compare: Compares two instances of DateTime and returns an integer that indicates whether the first instance is earlier than, the same as, or later than the second instance.

比较:比较 DateTime 的两个实例并返回一个整数,指示第一个实例是早于、相同还是晚于第二个实例。

CompareTo: Overloaded. Compares the value of this instance to a specified DateTime value and indicates whether this instance is earlier than, the same as, or later than the specified DateTime value.

比较:过载。将此实例的值与指定的 DateTime 值进行比较,并指示此实例是早于、等于还是晚于指定的 DateTime 值。

http://msdn.microsoft.com/en-us/library/system.datetime_members.aspx

http://msdn.microsoft.com/en-us/library/system.datetime_members.aspx

回答by shahkalpesh

I would suggest having a variable & using that to compare it with DateTime.Now

我建议有一个变量并使用它与 DateTime.Now 进行比较


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


This will help debugging easier & will help you read what is being returned by DataReader.
On a side note, I am guessing that the DB contains null value.

这将有助于更轻松地调试并帮助您阅读 DataReader 返回的内容。
附带说明一下,我猜数据库包含空值。

回答by Kevin Haines

First thing I'd do is print the two time values so I could see exactly what is happening. As mentioned by aku in the comments, check for timezone differences.

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

EDIT: Does the logic make sense?

编辑:逻辑有意义吗?

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

The Date/Times are logout times right? So this is check is "if the logout time is in the future, then..." - or am I completely misreading this?

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

回答by Kevin Haines

Thanks guys, I did set a variable to compare and nothing changed. i also ser to compare the Ticks and it did not work. When I subtracted the ticks it confirms to me that the date in the database was greater.

谢谢大家,我确实设置了一个变量进行比较,但没有任何改变。我还比较了 Ticks,但它不起作用。当我减去刻度时,它向我确认数据库中的日期更大。

回答by Sam Saffron

My guess,

我猜,

This could be to do with that while loop, are you looking at ALL the records in the db where sessionID matches?

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

Why is sessionID not a primary key?

为什么 sessionID 不是主键?

If it is, why the while loop?

如果是,为什么是 while 循环?

回答by Mark Brittingham

Ummm....how are you getting a "LogoutDateTime" that is greater than now? Have you bent time so that you know when your users are goingto log out?

嗯......你怎么得到一个比现在更大的“LogoutDateTime”?你有没有花时间知道你的用户什么时候退出?

If your database field has a default value in it (e.g. 1/1/1990) then this would explain your problem. Either that or this field should be null until they log out and you should test for null.

如果您的数据库字段中有一个默认值(例如 1/1/1990),那么这将解释您的问题。那个或这个字段应该为空,直到他们注销,你应该测试为空。

回答by aku

First of all it is a bad practice to work with DateTime that way. You should store value of DateTime.ToUniversalTime in the database and convert loaded DateTime to local time using DateTime.ToLocalTime method. Also it is not clear how much records will be returned from DB i.e. you can rewrite active several times. Just show us values of (DateTime)DataReader[0] and DateTime.Now (including DateTime.Kind property)

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

Also program logic looks obscure - why logout time is in future?

程序逻辑也看起来很模糊 - 为什么注销时间是在未来?

回答by aku

The LogoutDateTime is the expiry of the session. So what I check is if the session is expired.

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

The sessionID is the primary key, so the where clause can't return more than 1 result.

sessionID 是主键,所以 where 子句不能返回超过 1 个结果。

Why am I using a while? Because it's the way I know to use the SqlDataReader. Any better way? Please enlighten me.

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

Table Create script:

表创建脚本:

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]

Same method with log:

与日志相同的方法:

    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;
    }

Log:

日志:

DataBase Time :2009-01-13 01:32:28 Kind:Unspecified

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

DateTime.Now Time:2009-01-13 01:02:31 Kind:Local

DateTime.Now 时间:2009-01-13 01:02:31 种类:本地

active:False

活动:假

回答by spoulson

Your example code is comparing DateTimes with different DateTimeKind. Try converting them to the same kind, such as UTC. This blog postexplains the pitfalls of varying DateTimeKind in comparisons.

您的示例代码将 DateTimes 与不同的 DateTimeKind 进行比较。尝试将它们转换为相同类型,例如 UTC。这篇博文解释了不同 DateTimeKind 在比较中的缺陷。