Search code examples
c#datetimesubtractiontimespanformatexception

Trying to subtract DateTime "System.FormatException: String '12/9/2019 12:00:00 AM' was not recognized as a valid DateTime."


So I'm trying to make a check for an Order. The difference between ArriveTime and OrderDate should be between 10 minutes and 2 hours. I formatted everything to what I think was correct, but I still get the error.

The values I put in ArriveTime is DateTime.Today and in OrderDate I put in DateTime.Now.

Code:

private bool TimerRequirements(IOrderData orderData)
{
     DateTime arriveTime = DateTime.ParseExact(orderData.ArriveTime.ToString(), "dd-MM-yyyy hh:mm:ss:tt", CultureInfo.InvariantCulture);
     DateTime orderDate = DateTime.ParseExact(orderData.OrderDate.ToString(), "dd-MM-yyyy hh:mm:ss:tt", CultureInfo.InvariantCulture);


     if (orderData.ArriveTime != null && Convert.ToDateTime(arriveTime.Subtract(orderDate)) >= orderData.OrderDate.AddMinutes(10) ||
            orderData.ArriveTime != null && Convert.ToDateTime(arriveTime.Subtract(orderDate)) <= orderData.OrderDate.AddHours(2))
     {
         return true;
     }
     else
     {
         return false;
     }
}

Solution

  • Dates have no format, they are binary values. The code causes the error by trying to convert the dates ti strings then back to dates. Just use

    TimeSpan diff=orderData.ArriveTime - orderData.OrderDate;
    

    to get the difference as a TimeSpan, for example :

    var diff=orderData.ArriveTime - orderData.OrderDate;
    var inRange= (diff>=TimeSpan.FromMinutes(10) && diff<TimeSpan.FromHours(2));
    return inRange;
    

    The difference between two dates is a duration, not a date. In .NET that duration is represented by the TimeSpan class. You can generate TimeSpan values using its constructor, or through methods like FromHours and FromMinutes

    If OrderDate and ArriveTime are DateTime?, you'll get a TimeSpan? instead of TimeSpan. If any of those values is null, the difference will also be null.

    In this example :

    class Order{
        public DateTime? OrderDate{get;set;}
        public DateTime? ArriveTime{get;set;}
    }
    
    var orderData=new Order{};
    TimeSpan? diff=orderData.ArriveTime - orderData.OrderDate;
    

    diff is null. Both comparisons will return false so inRange will be false