简体   繁体   中英

Calculating the number of days a range of dates c#

Updated

I have a list of travels in the database with a various start and end dates, i would like to calculate the sum number of days that each travel has that corresponds with the defined range.

For example:

I want to query the number of days for the trip to Boston in the range following range:

RangeEnd is 27. Nov. 2017 RangeStart is 1. Nov. 2017

Here is my updated code:

 var travel = new List<Travel>
 {
     new Travel("Egypt", new DateTime(2017, 8, 4), new DateTime(2017, 8, 24) ),
     new Travel("Spain", new DateTime(2017, 11, 1), new DateTime(2017, 12, 10) ),
     new Travel("Detroit", new DateTime(2017,9, 15), new DateTime(2017, 12, 20) ),
     new Travel("Boston", new DateTime(2017,10, 15), new DateTime(2017, 11, 20) ),

 };
 var rangeStart = new DateTime(2017, 11, 1);
 var rangeEnd = new DateTime(2017, 11, 27);
 var Trip = travel.Where(t => t.Country=="Boston");
 var sumOfDays= Trip.Sum(t => ????);

The expected result for this case is 20 days. Can anyone help?

Thank you @Flydog57 for helping me figuring it out. i took your idea of calling another function and it worked with the range.

 var travel = new List<Travel>
 {
     new Travel("Egypt", new DateTime(2017, 8, 4), new DateTime(2017, 8, 24) ),
     new Travel("Spain", new DateTime(2017, 11, 1), new DateTime(2017, 12, 10) ),
     new Travel("Detroit", new DateTime(2017,9, 15), new DateTime(2017, 12, 20) ),
     new Travel("Boston", new DateTime(2017,10, 15), new DateTime(2017, 11, 20) ),

 };
 var rangeStart = new DateTime(2017, 11, 1);
 var rangeEnd = new DateTime(2017, 11, 27);

 var Trip= travel.Where(s => s != null && s.City == "Boston");

 var sumOfDays= Trip.Sum(t => GetTravelDaysWithinRange(t.Start,t.End,rangeStart, rangeEnd));

And the function that calculates the days is:

 public int GetTravelDaysWithinRange( DateTime start, DateTime end, DateTime rangeStart, DateTime rangeEnd)
 {
        int days = 0;
        while (start <= end)
        {
            if (start.Month>= rangeStart.Month && start.Month <= rangeEnd.Month && start.Year >= rangeStart.Year && start.Year <= rangeEnd.Year)
            {
                ++days;
            }
            start = start.AddDays(1);
        }
        return days;
  }

And the exact value of 20 was resulted :)))))

This can be done in 1 line

var Trip = travel.Where(t => t.Country == "Boston").Select(x => (x.EndDate - x.StartDate).TotalDays).FirstOrDefault();

You need first or default incase there are 0 results or more than 1 recuslt

How about something like this. The total I get is 55, which is what I expected:

Class Travel:

public class Travel
{
    public Travel(string where, DateTime start, DateTime end)
    {
        Where = where;
        StartDate = start;
        EndDate = end;
    }
    public string Where { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}

and then consuming it:

  var travel = new List<Travel>
  {
      new Travel("Egypt", new DateTime(2017, 8, 4), new DateTime(2017, 8, 24) ),
      new Travel("Spain", new DateTime(2017, 9, 1), new DateTime(2017, 10, 1) ),
      new Travel("Detroit", new DateTime(2017,9, 15), new DateTime(2017, 9, 20) ),

  };
  var sumOfTravelDays = travel.Sum(t => (t.EndDate - t.StartDate).Days);

What kind of issue are you seeing?

Update

Add this function to the Travel class (either in the class or as an extension method):

 public int GetTravelDaysWithinRange(DateTime rangeStart, DateTime rangeEnd)
 {
     //if everything is outside of the range to be considered, return 0
     if (rangeEnd < StartDate || rangeStart > EndDate)
     {
         return 0;
     }

     //Find the Max of StartDate and rangeStart 
     var startInRange = (rangeStart < StartDate) ? StartDate : rangeStart;
     //And the Min of EndDate and rangeEnd
     var endInRange = (rangeEnd > EndDate) ? EndDate : rangeEnd;
     //and get the number of days in-between (and then add 1 so Mon-Fri is 5 days, not 4)
     return (endInRange - startInRange).Days + 1;
 }

Now, when I run a variation of my original code, it does what I think you want:

 var travel = new List<Travel>
 {
     new Travel("Egypt", new DateTime(2017, 8, 4), new DateTime(2017, 8, 24) ),
     new Travel("Spain", new DateTime(2017, 11, 1), new DateTime(2017, 12, 10) ),
     new Travel("Detroit", new DateTime(2017,9, 15), new DateTime(2017, 12, 20) ),
     new Travel("Boston", new DateTime(2017,10, 15), new DateTime(2017, 11, 20) ),

 };
 var rangeStart = new DateTime(2017, 11, 1);
 var rangeEnd = new DateTime(2017, 11, 27);
 var sumOfDates = travel.Sum(t => t.GetTravelDaysWithinRange(rangeStart, rangeEnd));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM