1

I have a column of Datetime values in a table. I am using a LINQ query in a Controller to create model objects, where I am trying to perform a calculation to return the amount of days since the date value until now. The result updates another string variable depending on the result's value.

This is the LINQ query

        public ActionResult Index()
    {
        var result = from a in db.area
                     join c in db.sample
                     on a.location_id equals c.location_id into samples
                     let sample = samples.OrderByDescending(c => c.date_sampled).FirstOrDefault()
                     select new StatusModel
                     {
                         location_name = a.location_name,
                         latitude = a.latitude,
                         longitude = a.longitude,
                         status = sample.sample_status,
                         sampDate = sample.sample_date ?? DateTime.Now
                     };
        return View(result);
    }

And this is the method and constructor from my StatusModel to perform the calculation.

   public int difference;

    public StatusModel()
    {
        setStatus();
    }


    public void setStatus()
    {
        DateTime oldDate = sampDate;
        DateTime newDate = DateTime.Now;
        TimeSpan ts = newDate - oldDate;
        difference = ts.Days;
    }

The setStatus method works fine when I manually type in a date, i.e. if I set

DateTime oldDate = new DateTime(2016,2,9);

It returns as expected. However using the sampDate variable, it returns '736047' as the number of days for everything! The date in my database is set like '2016-01-04', when I run my project all dates in the Views are converted to MM-DD-YYYY, perhaps this is the problem.

  • I don't see any obvious problems with the code you've presented, so I would suspect that the dates in your database are somehow not getting converted properly to .NET `DateTime` values or the dates in your database are not being stored properly in the first place. – devuxer Mar 25 '16 at 23:36
  • @emerfan - can you paste full StatusModel? – whoah Mar 26 '16 at 08:01
  • Possible duplicate of [Calculate difference between two dates (number of days)?](http://stackoverflow.com/questions/1607336/calculate-difference-between-two-dates-number-of-days) – Meirion Hughes Mar 26 '16 at 08:11

2 Answers2

1

This notation:

   var x = new StatusModel {
           location_name = a.location_name,
           latitude = a.latitude,
           longitude = a.longitude,
           status = sample.sample_status,
           sampDate = sample.sample_date ?? DateTime.Now
    }

means exacly this:

var x = new StatusModel();

x.location_name = a.location_name;
x.latitude = a.latitude;
x.longitude = a.longitude;
x.status = sample.sample_status;
x.sampDate = = sample.sample_date ?? DateTime.Now;

Firstly, this code will run constructor for StatusModel, then it will insert values for properties. What is important in your case:

public StatusModel()
{
    setStatus();
}

You are running method setStatus() in your constructor, which is setting value for difference.

But this method is using sampDate which is not "initialized" yet - so sampDate will have a default value for DateTime, which is 0001-01-01. So now you have a reason, why difference returns 736047 days, because you are subtracting 2016-0001 (approximately).

Now it's time to resolve main issue - how to return difference of this two dates. It will be quite easy.

public int difference {
   get { return (sampDate - DateTime.Now).Days; }
}

public StatusModel()
{

}

Now you have a logic for difference in getter of this field, which is more "natural" in this case in my opinion. It will returns correct value for difference each time you will "ask" for value of this property, also during passing your model to view (using return View(model);)

whoah
  • 4,363
  • 10
  • 51
  • 81
  • Brilliant, really informative answer and thank you so much for the explanation - it makes perfect sense and was driving me nuts. I need to set a currentStatus based on the int difference, so I had placed the method in the constructor. Now I have a getter for currentStatus instead public string getStatus {get {if (difference >= 14){ return "Closed";}else{return status;}} –  Mar 26 '16 at 12:29
0

The object initializer gets called after the constructor; your code:

new StatusModel
                     {
                         location_name = a.location_name,
                         latitude = a.latitude,
                         longitude = a.longitude,
                         status = sample.sample_status,
                         sampDate = sample.sample_date ?? DateTime.Now
                     };

Will set the sampDate after the setStatus is executed, therefore the sampDate of the function will always be default(DateTime) and give you the same result (unless you're running it around midnight).

Stefano d'Antonio
  • 5,874
  • 3
  • 32
  • 45