关于C # DateTime值”零”。

DateTime “null” value

我找了很多,但找不到解决办法。如何处理能够包含未初始化值(相当于空值)的日期时间?我有一个类,它可能设置了日期时间属性值。我正在考虑将属性持有者初始化为datetime.minvalue,然后可以很容易地检查它。我想这是一个很常见的问题,你是怎么做到的?


对于正常日期时间,如果您根本不初始化它们,那么它们将与DateTime.MinValue匹配,因为它是值类型而不是引用类型。

您还可以使用可为空的日期时间,如下所示:

1
DateTime? MyNullableDate;

或较长的形状:

1
Nullable<DateTime> MyNullableDate;

最后,还有一种内置的方法来引用任何类型的默认值。这将返回引用类型的null,但对于datetime示例,它将返回与DateTime.MinValue相同的值:

1
default(DateTime)


如果使用.NET 2.0(或更高版本),则可以使用可为空的类型:

1
DateTime? dt = null;

1
Nullable<DateTime> dt = null;

然后:

1
dt = new DateTime();

您可以使用以下选项检查该值:

1
2
3
4
if (dt.HasValue)
{
  // Do something with dt.Value
}

或者你可以像这样使用它:

1
DateTime dt2 = dt ?? DateTime.MinValue;

您可以在此处阅读更多信息:http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx


日期时间?mydatetime获取;设置;

1
MyDateTime = (dr["f1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)dr["f1"]);


下面的方法也有效

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

请注意,属性publishdate应为datetime?


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

DateTime? myDate代替DateTime myDate


您可以为此使用可为空的日期时间。

1
Nullable<DateTime> myDateTime;

或者同样的事情:

1
DateTime? myDateTime;


可以使用可以为空的类。

1
DateTime? date = new DateTime?();

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

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

我总是把时间安排在DateTime.MinValue上。这样我就不会得到任何nullErrorException,我可以将它与一个我知道没有设置的日期进行比较。


可以将datetime设置为nullable。默认情况下,日期时间不可为空。您可以通过几种方法使其可以为空。在类型datetime之后使用问号?MyTime或使用可为空的通用样式。我在msdn上添加了几个链接。

使用可空的

可空的


请注意,当使用可为空的时,它显然不再是"纯"日期时间对象,因此您不能直接访问日期时间成员。我会尽力解释的。

通过使用nullable<>你基本上是把datetime包装在一个可以为空的容器中(谢谢你的泛型)——显然是它的目的。此容器有自己的属性,您可以调用这些属性来提供对上述日期时间对象的访问;在使用正确的属性(在本例中为nullable.value)之后,您就可以访问标准的日期时间成员、属性等。

所以,现在我们想到了访问datetime对象的最佳方法。有几种方法,第一种是目前最好的,第二种是"老兄为什么"。

  • 使用Nullable.Value属性,

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

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

  • 使用convert.to datetime()将可为空的对象转换为datetime,

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

  • 尽管答案在这一点上有很好的文档记录,但我相信nullable的使用可能值得发布。如果你不同意,对不起。

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


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

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

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

    现在,您可以在函数内部传递DTE,而不会出现任何问题。


    在对throws argumentnullException执行单元测试时,我遇到了与给datetime的参数提供空值相同的问题。在我的情况下,它使用以下选项工作:

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

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

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

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

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

    鉴于日期/时间数据类型的性质,它不能包含null值,即需要包含值,它不能为空或不包含任何内容。如果将日期/时间变量标记为nullable,则只能为其指定一个空值。所以你想做的是两件事中的一件(可能还有更多,但我只能想到两件):

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

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

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

    我的设想是我有一个BlogPost班。它有许多不同的字段/属性,但我在这个例子中只选择了两个。DatePublished是将文章发布到网站的时间,必须包含日期/时间值。DateModified是修改post时的值,因此它不必包含值,但可以包含值。

    1
    2
    3
    4
    5
    6
    public class BlogPost : Entity
    {
         public DateTime DateModified { get; set; }

         public DateTime DatePublished { get; set; }
    }

    使用ADO.NET从数据库中获取数据(分配DateTime.MinValue没有值):

    1
    2
    3
    BlogPost blogPost = new BlogPost();
    blogPost.DateModified = sqlDataReader.IsDBNull(0) ? DateTime.MinValue : sqlDataReader.GetFieldValue<DateTime>(0);
    blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);

    您可以通过将DateModified字段标记为nullable来完成我的第二点。现在,如果没有值,可以将其设置为null

    1
    public DateTime? DateModified { get; set; }

    使用ADO.NET从数据库中获取数据,它看起来与上面的方法有点不同(指定null而不是DateTime.MinValue):

    1
    2
    3
    BlogPost blogPost = new BlogPost();
    blogPost.DateModified = sqlDataReader.IsDBNull(0) ? (DateTime?)null : sqlDataReader.GetFieldValue<DateTime>(0);
    blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);

    我希望这有助于消除任何困惑。考虑到我的回答是大约8年后的事,你现在可能是一个专业的C程序员。