【问题标题】:Calculating the number of days a range of dates c#计算日期范围内的天数c#
【发布时间】:2019-04-12 02:37:42
【问题描述】:

更新

我在数据库中有一个旅行列表,其中包含不同的开始和结束日期,我想计算每次旅行的总天数与定义的范围相对应。

例如:

我想查询以下范围内去波士顿的行程天数:

RangeEnd 是 2017 年 11 月 27 日 RangeStart 是 2017 年 11 月 1 日

这是我更新的代码:

 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 => ????);

此案例的预期结果为 20 天。 有人可以帮忙吗?

【问题讨论】:

  • 那么travel12TimesCount 是否包含正确的数字?如果是这样,为什么不呢?
  • 不清楚你在问什么。你期望输出是什么,你得到了什么?
  • Sum(s =&gt; m.EndOfMonth 那是什么m
  • 如果你创建两个DateTime 对象并减去它们,你将得到一个TimeSpan。您可以从该对象读取天数。您还可以获得小时数(用于四舍五入)。
  • 该示例的预期输出为 26 - 给你:dotnetfiddle.net/b3LOzn

标签: c# ienumerable


【解决方案1】:

这样的事情怎么样。我得到的总数是 55,这是我的预期:

班级旅行:

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; }
}

然后消费它:

  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);

您遇到了什么样的问题?

更新

将此函数添加到 Travel 类(在类中或作为扩展方法):

 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;
 }

现在,当我运行我的原始代码的变体时,它会执行我认为您想要的操作:

 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));

【讨论】:

  • 感谢您的意见。问题是与变量无关: m.EndOfMonth 是 27. Nov. 2017 m.StartOfMonth 是 1. Nov. 2017 我想要达到的目标是只获得在这个范围内的天数.
  • @Sam:我已经更新了我的答案。我认为它应该满足您的需求
  • 不是真的 :( 在您的示例中,假设我们希望在 2017 年 11 月 1 日至 27 日的同一日期范围内获得波士顿旅行的天数。但我仍然无法这样做...
  • 我没有关注。我得到 11 月 1 日(因为它从 10 月 10 日开始,但你只考虑 11 月 1 日和 11 月 27 日之间的日期)到 11 月 20 日。我减去这两个得到 19 天。现在,如果我从周一到周五旅行是 5 天还是 4 天 - 你的规范是怎么说的?我的计算是 4 天(因为它是简单的减法)。如果你想要 5 天,那么,这是一个简单的逐一错误,你可以修复它(提示:在 GetTravelDaysWithinRange 中添加一个 - 你有一个调试器和一个编译器,应该能够修复它)。否则,这段代码通过了我所有的测试。
  • 哦,等一下,你更新了你的帖子(实际上是用我的代码)。如果您想提取到波士顿的旅行并获取该特定旅行的旅行天数(仅在 Nov1 到 Nov27 的范围内),请使用:var sumOfDates = travel.Where(t=&gt;t.Where == "Boston").Sum(t =&gt; t.GetTravelDaysWithinRange(rangeStart, rangeEnd));。 Where 子句将列表减少到只有一个条目,而 Sum 子句得出总旅行天数。而且,您还需要解决同样的问题
【解决方案2】:

感谢 @Flydog57 帮助我解决这个问题。我接受了你调用另一个函数的想法,它适用于范围。

 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));

而计算天数的函数是:

 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;
  }

结果是 20 的确切值 :)))))

【讨论】:

  • 顺便说一句,说“谢谢”的正确方式是对您认为有用的任何答案进行投票。如果其中一个答案是您最终用来解决问题的答案,您可以接受它。这样,几年后,当有人在谷歌上寻找与您类似的问题的解决方案时,他们会以良好的排序顺序找到答案。
  • 对于它的价值,我猜如果你将我的函数的最后一行从return (endInRange - startInRange).Days; 更改为return (endInRange - startInRange).Days + 1;,你会得到相同的答案。而且,它不是比较 DateTime 的位或循环迭代。
【解决方案3】:

这可以在 1 行中完成

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

如果有 0 个结果或超过 1 个 recuslt,您需要先或默认值

【讨论】:

  • 那没有考虑范围开始和结束日期。
猜你喜欢
  • 2011-02-05
  • 1970-01-01
  • 1970-01-01
  • 2018-12-15
  • 2021-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多