DateTime“空”值

我一直在寻找很多,但找不到解决scheme。 你如何处理应该能够包含一个未初始化的值(等于null)的date时间? 我有一个类可能有一个DateTime属性值设置或不。 我正在考虑将财产持有人初始化为DateTime.MinValue,然后可以很容易地进行检查。 我想这是一个很常见的问题,你怎么做?

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

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

 DateTime? MyNullableDate; 

或者更长的forms:

 Nullable<DateTime> MyNullableDate; 

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

 default(DateTime) 

如果您使用.NET 2.0(或更高版本),则可以使用可空types:

 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

约会时间? MyDateTime {获得;设置;}

 MyDateTime = (drOrder["Field1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)drOrder["Field1"]); 

我会考虑使用可空types 。

DateTime? myDate DateTime? myDate而不是DateTime myDate

您可以使用可空类。

 DateTime? date = new DateTime?(); 

你可以使用一个可为空的DateTime。

 Nullable<DateTime> myDateTime; 

或者是这样写的:

 DateTime? myDateTime; 

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

值得指出的是,尽pipeDateTimevariables不能为null ,但仍然可以在没有编译器错误的情况下将其与null进行比较:

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

您可以将“date时间”设置为“可空”。 默认情况下,DateTime不可为空。 您可以通过几种方式使其为空。 在typesDateTime之后使用问号? myTime或使用通用样式Nullable。 我在msdn上添加了一些链接。

使用可空

可空

这种方式也起作用

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

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

只是被警告 – 当使用Nullable它明显不再是一个“纯”的date时间对象,因此你不能直接访问DateTime成员。 我会尽力解释。

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

所以 – 现在想到的问题是访问DateTime对象的最佳方法。 有几种方法,第一是FAR最好,第二是“老兄为什么”。

  1. 使用Nullable.Value属性,

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

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

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

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

虽然现在的答案已经很好logging了,但我相信Nullable的使用可能值得一提。 对不起,如果你不同意。

编辑:删除了第三个选项,因为它是有点过于具体和案件有关。

尽pipe每个人都已经给出了答案,但我会提到一种方法,可以很容易地将date时间传递给函数

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

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

现在你可以在函数里面传递dte,没有任何问题。

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

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

在您的存储库中使用无效的date时间。

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

我有同样的问题,因为我不得不作为一个参数为DateTime的时候执行unit testing抛出ArgumentNullException.It在我的情况下使用以下选项:

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

鉴于date/时间数据types的性质,它不能包含null值,即它需要包含一个值,它不能为空或不包含任何内容。 如果您将date/时间variables标记为nullable则只能为其分配空值。 所以你想要做的是两件事情之一(可能会更多,但我只能想到两件事情):

  • 如果您没有该值,请为variables指定一个最小date/时间值。 您也可以指定最大date/时间值 – 无论哪种方式适合您。 在检查date/时间值时,只要确保站点一致。 决定使用minmax并坚持下去。

  • 将您的date/时间variables标记为可以为nullable 。 这样你可以设置你的date/时间variables为null如果你没有一个variables。

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

我的情况是我有一个BlogPost类。 它有许多不同的领域/属性,但我只select了两个例子。 DatePublished是发布到网站的post,并且必须包含date/时间值。 DateModified是一个post被修改时,所以它不必包含一个值,但可以包含一个值。

 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#程序员:)