306

我一直在寻找很多,但找不到解决方案。您如何处理应该能够包含未初始化值(相当于 null)的 DateTime?我有一个可能设置或不设置 DateTime 属性值的类。我正在考虑将属性持有者初始化为 DateTime.MinValue,然后可以轻松地对其进行检查。我想这是一个很常见的问题,你是怎么做到的?

4

15 回答 15

478

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

您还可以使用可为空的 DateTime,如下所示:

DateTime? MyNullableDate;

或者更长的形式:

Nullable<DateTime> MyNullableDate;

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

default(DateTime)

或者,在更新的 C# 版本中,

default
于 2008-10-21T12:56:04.887 回答
90

如果您使用的是 .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

于 2008-10-21T12:56:19.130 回答
43

以下方式也有效

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

请注意,属性 PublishDate 应该是 DateTime?

于 2017-02-06T06:21:38.307 回答
41

约会时间?我的日期时间{get;set;}

MyDateTime = (dr["f1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)dr["f1"]);
于 2010-04-28T16:08:16.100 回答
14

我会考虑使用可为空的类型

DateTime? myDate而不是DateTime myDate.

于 2008-10-21T12:56:11.157 回答
8

值得指出的是,虽然一个DateTime变量不能是null,但它仍然可以在null没有编译器错误的情况下进行比较:

DateTime date;
...
if(date == null) // <-- will never be 'true'
  ...
于 2014-04-30T22:00:23.920 回答
7

您可以将 DateTime 设置为 Nullable。默认情况下 DateTime 不可为空。您可以通过几种方式使其为空。在类型 DateTime 之后使用问号?myTime 或使用通用样式 Nullable。

DateTime? nullDate = null;

或者

DateTime? nullDate;
于 2008-10-21T13:27:33.853 回答
6

您可以使用可为空的类。

DateTime? date = new DateTime?();
于 2008-10-21T12:56:47.817 回答
6

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

Nullable<DateTime> myDateTime;

或者像这样写的同样的东西:

DateTime? myDateTime;
于 2008-10-21T12:56:57.207 回答
5

我总是把时间设置为DateTime.MinValue。这样我就不会收到任何 NullErrorException 异常,并且可以将其与我知道未设置的日期进行比较。

于 2008-10-21T12:57:16.443 回答
4

请注意 - 当使用 Nullable 时,它​​显然不再是“纯”日期时间对象,因此您无法直接访问 DateTime 成员。我会试着解释一下。

通过使用 Nullable<> 您基本上将 DateTime 包装在一个可以为空的容器(感谢泛型)中 - 显然它的目的。该容器有自己的属性,您可以调用这些属性来访问上述 DateTime 对象;使用正确的属性后 - 在本例中为 Nullable.Value - 然后您可以访问标准的 DateTime 成员、属性等。

所以 - 现在想到了访问 DateTime 对象的最佳方式的问题。有几种方法,1 号是 FAR 最好的,2 号是“老兄为什么”。

  1. 使用 Nullable.Value 属性,

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

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

  2. 使用 Convert.ToDateTime() 将可为空的对象转换为日期时间,

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

尽管此时答案已经有据可查,但我相信 Nullable 的使用可能值得一提。对不起,如果你不同意。

编辑:删除了第三个选项,因为它有点过于具体且取决于大小写。

于 2016-01-28T07:25:34.493 回答
2

虽然每个人都已经给了你答案,但我会提到一种可以很容易地将日期时间传递给函数的方法

[错误:无法转换 system.datetime?到 system.datetime]

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

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

于 2016-07-18T11:26:25.027 回答
1

如果您有时期望 null ,则可以使用以下内容:

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

在您的存储库中使用可为空的日期时间。

public Orders[] GetOrders(string id, DateTime? dateFrom, DateTime? dateTo){...}
于 2013-05-14T12:19:09.050 回答
1

我遇到了同样的问题,因为我在对 Throws ArgumentNullException 执行单元测试时必须将 Null 作为 DateTime 的参数。它在我的情况下使用以下选项起作用:

Assert.Throws<ArgumentNullException>(()=>sut.StartingDate = DateTime.Parse(null));
于 2017-02-17T22:48:47.773 回答
0

鉴于日期/时间数据类型的性质,它不能包含null值,即它需要包含值,它不能为空或不包含任何内容。如果您将日期/时间变量标记为nullablethen 您只能为其分配空值。因此,您要做的是两件事之一(可能还有更多,但我只能想到两件事):

  • 如果您没有值,请为您的变量分配一个最小日期/时间值。您也可以指定最大日期/时间值 - 无论哪种方式适合您。在检查日期/时间值时,请确保您在整个站点范围内保持一致。决定使用minormax并坚持下去。

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

让我用一个例子来说明我的第一点。DateTime变量类型不能设置为 null,它需要一个值,在这种情况下,如果没有值,我将其设置为的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# 专家级程序员了 :)

于 2016-07-26T09:43:22.530 回答