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。
值得指出的是,尽pipeDateTime
variables不能为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最好,第二是“老兄为什么”。
-
使用Nullable.Value属性,
DateTime date = myNullableObject.Value.ToUniversalTime(); //Works
DateTime date = myNullableObject.ToUniversalTime(); //Not a datetime object, fails
-
使用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/时间值时,只要确保站点一致。 决定使用
min
或max
并坚持下去。 -
将您的date/时间variables标记为可以为
nullable
。 这样你可以设置你的date/时间variables为null
如果你没有一个variables。
让我用一个例子来说明我的第一点。 DateTime
variablestypes不能设置为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#程序员:)