日期时间 "null" / 未初始化的值是什么?

321
如何处理应能包含未初始化值(相当于 null)的 DateTime?
我有一个类,其中可能设置 DateTime 属性值或不设置。我打算将属性持有者初始化为 DateTime.MinValue,这样可以轻松地进行检查。
我已经搜索了很多但找不到解决方案。我想这是一个相当普遍的问题,你怎么处理?
16个回答

4
请注意 - 当使用 Nullable 时,它显然不再是一个“纯”日期时间对象,因此您不能直接访问 DateTime 成员。我会尝试解释一下。
通过使用 Nullable<>,您基本上是将 DateTime 包装在一个容器中(感谢泛型),该容器可为空 - 显然是其目的。这个容器有自己的属性,您可以调用这些属性来访问前面提到的 DateTime 对象;在使用正确的属性 - 在这种情况下是 Nullable.Value - 之后,您就可以访问标准的 DateTime 成员、属性等。
所以 - 现在的问题是如何最好地访问 DateTime 对象。有几种方法,第一种绝对是最好的,而第二种则是“哥们为什么要这样”。
  1. 使用 Nullable.Value 属性,

    DateTime date = myNullableObject.Value.ToUniversalTime(); //有效

    DateTime date = myNullableObject.ToUniversalTime(); //不是日期时间对象,失败

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

    DateTime date = Convert.ToDateTime(myNullableObject).ToUniversalTime(); //有效但为什么...

虽然答案已经被充分记录,但我认为使用 Nullable 可能值得发帖。如果您不同意,请原谅。
编辑:删除了第三个选项,因为它有点过于具体和依赖于情况。

2

虽然其他人已经给出了答案,但我想提供一种更容易将日期时间传递到函数中的方法。

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

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

现在,您可以在不遇到任何问题的情况下将dte传递到函数中。

1
如果您有时期望为null,可以使用类似以下的代码:
var orderResults = Repository.GetOrders(id, (DateTime?)model.DateFrom, (DateTime?)model.DateTo)

在你的代码库中使用可空日期时间。
public Orders[] GetOrders(string id, DateTime? dateFrom, DateTime? dateTo){...}

1

我遇到了与单位测试Throws ArgumentNullException相关的问题,由于需要将DateTime的参数设置为Null,但是解决方案很简单,只需要使用以下选项即可:

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

0

由于日期/时间数据类型的特性,它不能包含null值,即它需要包含一个值,不能是空白或不包含任何内容。如果您将日期/时间变量标记为nullable,那么只能将null值分配给它。因此,您要做的事情有两种(可能还有更多,但我只能想到两种):

  • 如果您没有该变量的值,则将最小日期/时间值分配给您的变量。您也可以分配最大日期/时间值-无论哪种方式适合您。只需确保在检查日期/时间值时整个站点保持一致。决定使用minmax并坚持使用。

  • 将日期/时间变量标记为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#程序员了 :)


0
问题本身就是正确的答案。 "如果日期时间为空,您如何处理?" 问者在最后给出了DateTime.MinValue的答案。我的想法是,问者的方法应该是稍微改变一下的方式。我建议使用DateTime.MaxValue进行比较,因为它不会发生在12/31/9999之前。如果为真,则将字段显示为其他日期以外的内容。以下是示例;
 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")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接