DateTime“null"价值

我一直在寻找,但没有找到解决办法。如何处理应该能够包含未初始化值(相当于null)的DateTime ?我有一个类,它可能有一个DateTime属性值设置或没有。我正在考虑将属性持有人初始化为DateTime。MinValue,然后可以很容易地检查。我想这是一个很常见的问题,你是怎么做到的?

687699 次浏览

对于普通的DateTimes,如果你根本不初始化它们,那么它们将匹配DateTime.MinValue,因为它是一个值类型而不是引用类型。

你也可以使用一个可空的DateTime,像这样:

DateTime? MyNullableDate;

或较长的形式:

Nullable<DateTime> MyNullableDate;

最后,有一种内置的方式来引用任何类型的默认值。这将为引用类型返回null,但对于我们的DateTime示例,它将返回与DateTime.MinValue相同的值:

default(DateTime)

或者,在c#的最新版本中,

default

我会考虑使用可空类型

DateTime? myDate代替DateTime myDate

如果你使用。net 2.0(或更高版本),你可以使用可空类型:

DateTime? dt = null;

Nullable<DateTime> dt = null;

之后:

dt = new DateTime();

你可以用:

if (dt.HasValue)
{
// Do something with dt.Value
}

或者你可以这样用:

DateTime dt2 = dt ?? DateTime.MinValue;

你可以在这里阅读更多:
http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx < / p >

可以使用可空类。

DateTime? date = new DateTime?();

您可以为此使用一个可空的DateTime。

Nullable<DateTime> myDateTime;

也可以这样写

DateTime? myDateTime;

我总是将时间设置为DateTime.MinValue。这样我就不会得到任何NullErrorException,我可以将它与我知道没有设置的日期进行比较。

您可以将DateTime设置为Nullable。默认情况下DateTime不是空的。有几种方法可以使它为空。在类型DateTime后使用问号?myTime或使用泛型样式Nullable。

DateTime? nullDate = null;

DateTime? nullDate;

DateTime吗?MyDateTime{获取;设置;}

MyDateTime = (dr["f1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)dr["f1"]);

如果你有时期望null,你可以使用这样的东西:

var orderResults = Repository.GetOrders(id, (DateTime?)model.DateFrom, (DateTime?)model.DateTo)

在存储库中使用可空datetime。

public Orders[] GetOrders(string id, DateTime? dateFrom, DateTime? dateTo){...}

值得指出的是,虽然DateTime变量不能是null,但它仍然可以与null进行比较而不会出现编译器错误:

DateTime date;
...
if(date == null) // <-- will never be 'true'
...

只是需要注意的是,当使用Nullable对象时,它显然不再是一个“纯”datetime对象,因此你不能直接访问datetime成员。我会尽力解释的。

通过使用Nullable<>,你基本上是将DateTime包装在一个容器(感谢泛型)中,它是可空的——这显然是它的目的。这个容器有自己的属性,你可以调用它来访问前面提到的DateTime对象;在使用正确的属性后-在这种情况下是Nullable。值-然后您可以访问标准的DateTime成员,属性等。

那么,现在我想到的问题是访问DateTime对象的最佳方式。有几种方法,第一种是目前为止最好的,第二种是“伙计,为什么”。

  1. 使用Nullable。价值属性,

    DateTime date = myNullableObject.Value.ToUniversalTime(); //Works

    DateTime date = myNullableObject.ToUniversalTime(); //Not a datetime object, fails < / p >

  2. 使用Convert.ToDateTime()将可空对象转换为datetime,

    DateTime date = Convert.ToDateTime(myNullableObject).ToUniversalTime(); //works but why... < / p >

虽然答案在这一点上有很好的文档,但我相信Nullable的用法可能值得发表。如果你不同意,我很抱歉。

edit:删除了第三个选项,因为它有点过于具体和大小写依赖。

虽然每个人都已经给出了答案,但我将提到一种容易将datetime传递到函数中的方法

[ERROR:cannot convert system.datetime?]system.datetime)

DateTime? dt = null;
DateTime dte = Convert.ToDateTime(dt);

现在你可以在函数内部传递dte了,没有任何问题。

鉴于日期/时间数据类型的性质,它不能包含null值,即它需要包含一个值,它不能为空或不包含任何内容。如果将日期/时间变量标记为nullable,则只能将空值赋给它。所以你要做的是两件事中的一件(可能还有更多,但我只能想到两件):

  • 如果变量没有值,则为其分配一个最小日期/时间值。您也可以指定一个最大日期/时间值-任何适合您的方式。只要确保在检查日期/时间值时在站点范围内保持一致即可。决定使用minmax并坚持使用它。

  • 将日期/时间变量标记为nullable。这样,如果你没有变量,你可以将日期/时间变量设置为null

让我用一个例子来说明我的第一点。DateTime变量类型不能设置为空,它需要一个值,在这种情况下,如果没有值,我将把它设置为DateTime的最小值。

我的场景是我有一个BlogPost类。它有许多不同的字段/属性,但在这个例子中我只选择了两个。DatePublished是帖子发布到网站的时间,必须包含日期/时间值。DateModified是当一个帖子被修改时,所以它不必包含一个值,但可以包含一个值。

public class BlogPost : Entity
{
public DateTime DateModified { get; set; }


public DateTime DatePublished { get; set; }
}

使用ADO.NET从数据库中获取数据(分配DateTime.MinValue是没有值):

BlogPost blogPost = new BlogPost();
blogPost.DateModified = sqlDataReader.IsDBNull(0) ? DateTime.MinValue : sqlDataReader.GetFieldValue<DateTime>(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);

你可以通过将DateModified字段标记为nullable来实现我的第二点。现在你可以将它设置为null,如果它没有值的话:

public DateTime? DateModified { get; set; }

使用ADO.NET从数据库中获取数据,它看起来与上面的方式略有不同(分配null而不是DateTime.MinValue):

BlogPost blogPost = new BlogPost();
blogPost.DateModified = sqlDataReader.IsDBNull(0) ? (DateTime?)null : sqlDataReader.GetFieldValue<DateTime>(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);

我希望这有助于澄清任何困惑。考虑到我的回答是大约8年后,你现在可能是一个c#编程专家:)

下面的方法也可以

myClass.PublishDate = toPublish ? DateTime.Now : (DateTime?)null;

请注意属性PublishDate应该是DateTime?

我有同样的问题,因为我必须给Null作为DateTime的参数,同时执行单元测试抛出ArgumentNullException。它在我的情况下工作,使用以下选项:

Assert.Throws<ArgumentNullException>(()=>sut.StartingDate = DateTime.Parse(null));

问题本身给出了正确的答案。“如果datetime为空,您将如何处理?”提问者在最后用DateTime.MinValue给出答案。我的想法是提问者的方式应该是不变的。我建议使用DateTime。MaxValue比较,因为它不会发生直到12/31/9999。如果为真,则将field显示为日期以外的其他内容。下面是一个例子;

 DateNotified = DBNull.Value.Equals(reader["DateNotified"])? Convert.ToDateTime(reader["DateNotified"]): DateTime.MaxValue

和前端 如果你使用的是Grid,那么

columns.Add(col => col.DateNotified).Css("text-right").Titled("Date Notified").RenderValueAs(c => c.DateNotified.ToString("MM/dd/yyyy").Equals(DateTime.MaxValue) ? "":c.DateNotified.ToString("MM/dd/yyyy"));

或者一个简单的观点

@Model.DateNotified.ToString("MM/dd/yyyy").Equals(DateTime.MaxValue) ? "":Model.DateNotified.ToString("MM/dd/yyyy")