【问题标题】:Comparing nullable DateTime?比较可为空的日期时间?
【发布时间】:2012-12-02 19:50:12
【问题描述】:

寻找比以下更好的方法来比较可为空的日期时间:

有什么建议吗?

// myobject.ExpireDatetime is of DateTime?
//
if (!myobject.ExpireDateTime.IsNull() && DateTime.Compare((DateTime)myobject.ExpireDateTime, DateTime.Now.ToUniversalTime()) < 0)
{ //error! }    

已编辑:抱歉混淆...myobject.ExpireDatetime 是类型 日期时间。

【问题讨论】:

  • 在 C# 中,单词 object 是一个关键字,它不能用作标识符(除非你写成 @object)。我认为不清楚您是否有一个可能是空引用的盒装 DateTime,或者您是否有一个未装箱的“真正”可为空的 DateTime (DateTime?)。
  • 这能回答你的问题吗? Compare nullable datetime objects

标签: c# c#-4.0 datetime


【解决方案1】:

你的问题对我来说不是很清楚,但如果我们有的话

DateTime? ExpireDateTime;  // could be a variable or a property

随便说说

if (ExpireDateTime < DateTime.UtcNow)
{
  ...
}

如果ExpireDateTimenullHasValue 为假),则可以。一些没有经验的开发者会很难理解lifted operators,所以为了更清楚,你可以写

if (ExpireDateTime < (DateTime?)DateTime.UtcNow)
{
  ...
}

相同,但更易于阅读和理解。

永远不要.Value 如果可空值可能为空,当然。如果你这样做,你会得到一个InvalidOperationException "Nullable object must have a value"

【讨论】:

  • 太棒了!是的,这就是我真正追求的解释。也就是说,如何通过检查值是否不为空来比较可空日期时间而不短路逻辑...然后检查可空值 if (val.isnotnull && val.iswithinconstraint)
  • 但是,(default(DateTime?) DateTime.UtcNow) 也是假的
  • @labroo 当然可以。所以对于可空对象我们没有“trichotomy”,所以有时x &lt; yx == yx &gt; y 都是false
  • 这也取决于具体的业务需求。在某些情况下,我可能希望将空日期视为“大于”任何有效日期。例如:minDate = d1 &lt; d2 ? d1 : d2,其中所有三个日期都可以为空 - 在这种情况下,我希望 minDate 接收实际有效日期(如果有),但不为空,除非 d1 和 d2 都为空。
  • @JustAMartin 如果你真的想要,你可以写!(ExpireDateTime &gt;= DateTime.UtcNow),如果null不涉及,则与ExpireDateTime &lt; DateTime.UtcNow相同,但在涉及null时具有相反的值。但是,阅读 !ExpireDateTime.HasValue || ExpireDateTime.Value &lt; DateTime.UtcNow 之类的内容可能更容易,具体取决于口味。
【解决方案2】:

我建议您使用以下内容:

int y = Nullable.Compare<DateTime>(DateTime.UtcNow, x); 

// x is the nullable date time object.
// y will be '-1' if x is greater than DateTime.UtcNow

【讨论】:

    【解决方案3】:

    编译器lifts 变量并生成代码以检查空值。

    > new DateTime?()
    null
    > DateTime.Now > null
    false
    > DateTime.Now < null
    false
    
    > new int?()
    null
    > 10 >= null
    false
    > 10 =< null
    false
    > 10 == null
    false
    > 10 != null
    true
    

    知道了这一点,你就可以编写简单的代码了。

    // d is a DateTime? 
    DateTime now = DateTime.Now;
    
    bool after = d > now;
    bool before = d < now;
    bool today = d?.Date == now.Date;
    

    如果 d 为 null,一切都将为 false,否则它将像正常的 DateTime 比较一样工作。

    【讨论】:

      【解决方案4】:

      如果ExpireDateTimeNullable&lt;DateTime&gt;,我会改为:

      if (ExpireDateTime.HasValue && ExpireDateTime < DateTime.Now.ToUniversalTime())
      { 
      }
      

      【讨论】:

        【解决方案5】:

        使用可空对象的Value 属性:

        objet.ExpireDateTime.Value
        

        if (!object.ExpireDateTime.IsNull() 
            && DateTime.Compare(objet.ExpireDateTime.Value, 
                                DateTime.Now.ToUniversalTime()) < 0)
        { 
        }    
        

        【讨论】:

        • 原始问题仍然有味道,因为(在通常的实现中)System.Object 没有名为ExpireDateTimestatic 成员(因此它仍然无法编译)。
        • @JeppeStigNielsen - ExpireDateTime 可能是一种扩展方法。
        • @Oded 你不能那样扩展。即使使用扩展方法,您也需要在点之前使用标识符或普通表达式 (.)。例如(new object()).ExpireDateTime()typeof(object).ExpireDateTime()@object.ExpireDateTime() 都可能使用一些(非常疯狂的)扩展方法进行编译。但是object 有问题。此外,如果它是一个方法,你不能只说.IsNull 而没有先invoking ExpireDateTime。简而言之,它永远不会像现在这样有效。
        • 抱歉给您带来了困惑...object.ExpireDateTime 是 DateTime 类型。
        • @JaJ 在代码中写object "dot" ExpireDateTime 是不合法的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多