0

I have a data table that contains a "CreateDate" and an "UpdateDate" columns. I am trying to find the smallest CreateDate and largest UpdateDate. It is not difficult but columns can contain NULL (or DBNull) and this is tripping me. I was using the following:

DateTime dtMin = DateTime.MaxValue;
DateTime dtMax = DateTime.MinValue;

foreach(DataRow dr in dt.Rows)
{
    DateTime dtCreateDate = dr.Field<DateTime>("CreateDate");
    DateTime dtUpdateDate = dr.Field<DateTime>("UpdateDate");
    dtMin = dtMin > dtCreateDate ? dtCreateDate : dtMin;
    dtMax = dtMax > dtUpdateDate ? dtMax : dtUpdateDate;
}

Until I hit a row with a NULL date.

Willy David Jr
  • 8,604
  • 6
  • 46
  • 57
NoBullMan
  • 2,032
  • 5
  • 40
  • 93

5 Answers5

0

Check first if the value on the datarow is null before proceeding:

foreach (DataRow dr in dt.Rows)
     {
       if (dr["CreateDate"] != null && dr["UpdateDate"] != null)
         {
           //TODO: Logic here
         }
     }
Willy David Jr
  • 8,604
  • 6
  • 46
  • 57
0

You should to check DBNull.Value and null before you parse values to DateTime because DateTime datetype cannot contain null values. Remember that DBNull.Value and object null are 2 different things

By declaring DateTime?, dtCreateDate, dtUpdateDate can contain null value. Then, if you receive a null value, you can skip to compare it with dtMin and dtMax.

foreach (DataRow dr in dt.Rows)
{
    DateTime? dtCreateDate = dr["CreateDate"] == DBNull.Value || dr["CreateDate"] == null ? (DateTime?) null : dr.Field<DateTime>("CreateDate");
    DateTime? dtUpdateDate = dr["UpdateDate"] == DBNull.Value || dr["UpdateDate"] == null ? (DateTime?) null: dr.Field<DateTime>("UpdateDate");


    dtMin = dtCreateDate == null ? dtMin : (dtMin > dtCreateDate ? dtCreateDate : dtMin);
    dtMax = dtUpdateDate == null ? dtMax : (dtMax > dtUpdateDate ? dtMax : dtUpdateDate);

}
Hieu Le
  • 1,042
  • 8
  • 18
  • I thought about this, but if in first iteration I found a valid dtCraeteDate and in the next iteration I get a NULL date to compare, I don't want to set dtCreatDate back to DateTime.MinValue. – NoBullMan May 17 '17 at 02:24
  • I updated my suggestion. Declare DateTime? which allow you to contain null value – Hieu Le May 17 '17 at 02:31
0

You can use Min & Max compute that are supported by data tables. Other option is to use LINQ to find min & max. For reference please see answer on following link. How to select min and max values of a column in a datatable?

Community
  • 1
  • 1
0

This map help you

foreach (DataRow dr in dt.Rows)
{
    DateTime? dtCreateDate = (DateTime?)dr["CreateDate"];
    DateTime? dtUpdateDate = (DateTime?)dr["UpdateDate"];
    dtMin = (dtCreateDate != null && dtMin > dtCreateDate) ? dtCreateDate.Value : dtMin;
    dtMax = (dtUpdateDate != null && dtMax < dtUpdateDate) ? dtUpdateDate.Value : dtMax;
}
Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
0

Here use coalescing operator and conditional operator ,for managing the conditions :

foreach (DataRow dr in dt.Rows)
{
    // Collecting data from DataRow
    DateTime? dtCreateDate =dr.Field<DateTime?>("CreateDate")??(DateTime?)null;
    DateTime? dtUpdateDate=dr.Field<DateTime?>("UpdateDate")??(DateTime?)null;

    // Manupulating condition to get required result
    dtMin = dtCreateDate != null ?(dtMin > dtCreateDate ? dtCreateDate : dtMin) : dtMin;
    dtMax = dtUpdateDate != null ?(dtMax > dtUpdateDate ? dtMax : dtUpdateDate): dtMax;
}
UJS
  • 853
  • 1
  • 10
  • 16