【问题标题】:DateTime.Parse takes min date value if null如果为 null,则 DateTime.Parse 采用最小日期值
【发布时间】:2015-08-19 13:22:53
【问题描述】:

我有一个 asp.net 应用程序,其中我有一个文本框来输入日期时间值,它保存在数据库中。

现在,当我尝试检索日期时,如果日期为空,它会显示 1/1/0001 12:00:00 AM。

this.FirstReceivedDate = DateTime.Parse(dr["FirstReceivedDate"].ToString());

抱歉,要求已更改。现在,如果 FirstReceivedDate 为空,我想显示空白 ('')。

我该怎么做?

【问题讨论】:

  • 它在数据库中实际上是空的吗?
  • DateTime.Parse() 如果是来自数据库的DBNull.Value,则会抛出异常。我怀疑你在实际的数据库表中有那个底线日期时间..?请验证。
  • 我不相信数据库中的数据与您认为的相符。我无法使用null、空字符串等值重现这种情况。请验证 dr["FirstReceivedDate"].ToString() 返回的内容。
  • 请注意,FirstRecievedDate 应该是数据库中的 Date 类型列。在这种情况下,您不需要解析它。只需使用this.FirstReceivedDate = = dr.Field<DateTime>("FirstReceivedDate");
  • 是的,它在数据库中为空。此外,该字段是数据库中的日期时间。

标签: c# asp.net .net datetime nullable


【解决方案1】:

您可以尝试以下方法:

DateTime date = DateTime.Parse(dr["FirstReceivedDate"].ToString());
this.FirstReceivedDate = date != DateTime.MinValue ? date : DateTime.Now;

既然解析正确,这应该可以工作。

或者,如果您想要一个日期为空时的值,您可以尝试这样的操作:

DateTime date;
if(DateTime.TryParse(dr["FirstReceivedDate"], out date))
    this.FirstReceivedDate = date != DateTime.MinValue ? date : DateTime.Now;
else
    this.FirstReceivedDate = DateTime.Now; // or whatever you want to do if "FirstReceivedDate" is not a valid date.

【讨论】:

  • OP 的DateTime.Parse() 没有格式化异常,因此DateTime.TryParse() 不会返回false 的坏情况。
  • 这是一个天真的尝试,如果 dr["FirstReceivedDate"] 为空,则执行 tostring 时会出现异常啊hhhhh
  • @Juan 如果该字段为空,我们真的不知道用户想要做什么。他真的想要一个价值,还是让它爆炸?
【解决方案2】:

DateTime 变量(以及所有其他值类型)不能为空(除非您明确将它们声明为可为空),因为它们必须保存一个值。 (你现在说它可以为空的)

您需要的修复非常简单 - 您只需检查数据行中字段的空值并适当地分配空 DateTime(如果是),否则使用 DataRow.Field<T> 方法分配类型安全的数据库值:

this.FirstReceivedDate = dr["FirstReceivedDate"] == DBNull.Value ? (DateTime?)null : dr.Field<DateTime>("FirstReceivedDate");

实际上考虑一下,您应该能够执行以下操作来传播空值(未经测试):

this.FirstReceivedDate = dr.Field<DateTime?>("FirstReceivedDate");

正如您所说,如果数据库值为空,则需要一个空白字符串,那么当您显示它时,您只需检查 DateTime 的空值:

textBox1.Text = this.FirstReceivedDate == null ? "" : this.FirstReceivedDate.ToString();

【讨论】:

  • 我已将变量声明为可为空。但它会是相同的修复吗?
  • 我已经更新了我的答案,现在你已经提到了。
【解决方案3】:
this.FirstReceivedDate = DateTime.Parse(dr["FirstReceivedDate"].ToString());

if (this.FirstReceivedDate == DateTime.MinValue)
    this.FirstReceivedDate = DateTime.Now;

测试FirstReceivedDate 是否等于 DateTime 的最小值(您在问题中指定)。如果是这样,只需将其设置为当前日期/时间。

【讨论】:

    【解决方案4】:
    DateTime date = DateTime.Parse(dr["FirstReceivedDate"].ToString());     
    this.FirstReceivedDate = date = =default(DateTime) ? DateTime.Now : date;
    

    这里真正的问题是当您说日期时间可以为空时,为什么会收到 1/1/0001 12:00:00 AM?,您应该收到 DBNull,检查您的数据库,该字段应该接受空值。

    【讨论】:

      【解决方案5】:

      我创建了这个扩展方法来尝试转换为日期时间,如果函数返回 null 则该值不是有效的日期时间

           public static DateTime? ToDateTimeCheck2(this string valor)
      {
             var isDate = true;
      
              DateTime dt;
              isDate  = DateTime.TryParse(valor, out dt);
      
              if (isDate)
                  return dt;
              else
              return null;
      
      
      }
      

      然后在你的代码中你可以说

      this.FirstReceivedDate =( dr["FirstReceivedDate"].ToDatetimeCheck2() == null)? "" : dr["FirstReceivedDate"].ToDatetimeCheck2();
      

      没有扩展方法的其他选项:

       string t = "123";
      
                  DateTime result;
      
                  string testing = (DateTime.TryParse(t,out result ))? result.ToShortDateString() : string.Empty;
      

      【讨论】:

      • 我在很多项目中都使用了这段代码,没有任何问题。这里的想法是在一个类中创建这个扩展方法作为助手。如果您正在使用像实体框架这样的 ORM 映射器,并且如果在这种情况下日期时间的值为 null 或空,那么您将添加一条记录,那么您会将 null 发送到实体框架的对象,这将有助于框架做出反应,因为值为空。
      • tbh DateTime.TryParse 做同样的事情。
      • TryParse 将返回一个布尔值,指示转换是否成功。扩展方法是避免大量代码是这个测试的助手。
      • 如果转换成功,它还会传递解析的日期,如果转换不成功,则日期为空。
      • 如果测试不好使用 tryparse,out 变量将得到 1/1/0001 12:00:00 AM The out 变量不可为空。
      【解决方案6】:

      试试这个:

      DataRow dbField = dr["FirstReceivedDate"];
      
      this.FirstReceivedDate = dbField == null 
          ? String.Empty 
          : dbField.ToString() ;
      

      【讨论】:

      • 我认为您不能将String.Empty 分配给DateTime。当你真的只需要一个时,你也在做 2 次解析操作。
      • OP 显示目标字段是一个字符串。是的,您可以改为创建一个变量。更新了答案。
      • 它返回一个错误说“运算符'=='不能应用于'System.DateTime和'string'类型的操作数”
      • 已更新。有一个放错地方的括号。
      • @BillMartin 取决于您可能需要在.ToString() 调用中指定日期格式的文化。
      【解决方案7】:

      以下代码有效。

      string date = dr["FirstReceivedDate"].ToString();
      this.FirstReceivedDate = date == "" ? (DateTime?)null : DateTime.Parse(date);
      

      感谢大家的帮助。

      【讨论】:

        猜你喜欢
        • 2023-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多