题
我一直在寻找很多但找不到解决方案。如何处理应该能够包含未初始化值(相当于 null)的 DateTime?我有一个类可能设置或未设置 DateTime 属性值。我正在考虑将属性持有者初始化为 DateTime.MinValue,然后可以轻松检查。我想这是一个很常见的问题,你是如何做到的?
解决方案
对于普通的DateTimes,如果你根本没有初始化它们,那么它们将匹配 DateTime.MinValue
,因为它是一个值类型而不是引用类型。
你也可以使用可以为空的DateTime,如下所示:
DateTime? MyNullableDate;
或更长的形式:
Nullable<DateTime> MyNullableDate;
最后,有一种内置方式可以引用任何类型的默认值。这会为引用类型返回 null
,但对于我们的DateTime示例,它将返回与 DateTime.MinValue
相同的内容:
default(DateTime)
其他提示
如果您使用的是.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
的DateTime? MyDateTime {获得;设置;}
MyDateTime = (dr["f1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)dr["f1"]);
以下方式也适用
myClass.PublishDate = toPublish ? DateTime.Now : (DateTime?)null;
请注意,属性PublishDate应该是DateTime?
我考虑使用可空类型
<代码>的DateTime? myDate 而不是 DateTime myDate
。
您可以使用可以为空的类。
DateTime? date = new DateTime?();
您可以使用可为空的DateTime。
Nullable<DateTime> myDateTime;
或者像这样写的东西:
DateTime? myDateTime;
我总是将时间设置为 DateTime.MinValue
。这样我就不会得到任何NullErrorException,我可以将它与我知道未设置的日期进行比较。
值得指出的是,虽然 DateTime
变量不能是 null
,但它仍然可以与 null
进行比较而不会出现编译器错误:
DateTime date;
...
if(date == null) // <-- will never be 'true'
...
您可以将DateTime设置为Nullable。默认情况下,DateTime不可为空。您可以通过几种方式使其可以为空。在DateTime类型后使用问号? myTime或使用通用样式Nullable。我在msdn上添加了几个链接。
请注意 - 当使用Nullable时,它显然不再是“纯”日期时间对象,因此您无法直接访问DateTime成员。我会试着解释一下。
使用Nullable&lt;&gt;你基本上把DateTime包装在一个可以为空的容器中(谢谢泛型) - 显然是它的目的。此容器具有自己的属性,您可以调用它们来访问上述DateTime对象;在使用正确的属性(在本例中为Nullable.Value)之后,您可以访问标准的DateTime成员,属性等。
所以 - 现在想到了访问DateTime对象的最佳方法的问题。有几种方法,1号是FAR最好的,2号是“dude why”。
-
使用Nullable.Value属性
DateTime date = myNullableObject.Value.ToUniversalTime(); //工程代码>
DateTime date = myNullableObject.ToUniversalTime(); //不是日期时间对象,失败
-
使用Convert.ToDateTime()将可空对象转换为datetime,
DateTime date = Convert.ToDateTime(myNullableObject).ToUniversalTime(); //有效,但为什么......
醇>
虽然答案在这一点上有详细记载,但我相信Nullable的使用可能值得张贴。对不起,如果你不同意。
编辑:删除了第三个选项,因为它有点过于具体和依赖于案例。
尽管每个人都已经给出了答案,但我会提到一种方法,可以很容易地将日期时间传递给函数
[错误:无法转换system.datetime?到system.datetime]
DateTime? dt = null;
DateTime dte = Convert.ToDateTime(dt);
现在你可以在函数内部传递dte而没有任何问题。
如果你有时候,期望null,你可以使用这样的东西:
var orderResults = Repository.GetOrders(id, (DateTime?)model.DateFrom, (DateTime?)model.DateTo)
在您的存储库中使用null-able datetime。
public Orders[] GetOrders(string id, DateTime? dateFrom, DateTime? dateTo){...}
我遇到了同样的问题,因为在执行Throws ArgumentNullException的单元测试时,我必须将Null作为DateTime的参数。在我的情况下使用以下选项工作:
Assert.Throws<ArgumentNullException>(()=>sut.StartingDate = DateTime.Parse(null));
鉴于日期/时间数据类型的性质,它不能包含 null
值,即它需要包含一个值,不能为空或不包含任何内容。如果将日期/时间变量标记为 nullable
那么只能给它分配一个空值。所以你想做的是两件事之一(可能还有更多,但我只能想到两件事):
如果您没有变量值,请为变量分配一个最小日期/时间值。您还可以指定最大日期/时间值 - 无论哪种方式适合您。只需确保在检查日期/时间值时在站点范围内保持一致即可。决定使用
min
或者max
并坚持下去。将您的日期/时间变量标记为
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# 程序员:)