【问题标题】:Split date range into several specific date range chunks将日期范围拆分为几个特定的​​日期范围块
【发布时间】:2018-10-27 09:46:32
【问题描述】:

我有具有特定值的定期日期范围列表:

14.09.2012 - 31.12.2015 = 8.25
01.01.2016 - 13.06.2016 = 11.00
14.06.2016 - 18.09.2016 = 10.50
19.09.2016 - 26.03.2017 = 10.00
27.03.2017 - 01.05.2017 = 9.75
02.05.2017 - 18.06.2017 = 9.25
19.06.2017 - 17.09.2017 = 9.00
18.09.2017 - 29.10.2017 = 8.50
30.10.2017 - 17.12.2017 = 8.25
18.12.2017 - 11.02.2018 = 7.75
12.02.2018 - 25.03.2018 = 7.50
26.03.2018 - 16.09.2018 = 7.25
17.09.2018 - NOW = 7.50

我正在寻找一种将一个输入数据范围划分为上述数据范围并考虑系数值的方法。

例如,如果我有输入日期范围01.01.2016 - 09.02.2016,我需要得到一个输出日期范围和系数:

01.01.2016 - 13.06.2016 = 11.00

但如果我有输入日期范围01.01.2016 - 29.04.2017,我需要得到以下范围和系数:

14.09.2012 - 31.12.2015 = 8.25 
01.01.2016 - 13.06.2016 = 11.00 
14.06.2016 - 18.09.2016 = 10.50 
19.09.2016 - 26.03.2017 = 10.00
27.03.2017 - 01.05.2017 = 9.75

输出数据类:

public class OutputItem 
{

    public OutputItem()
    {

    }

    public DateTime Start { get; set; } = new DateTime();

    public DateTime End { get; set; } = new DateTime();

    public double Coeff { get; set; } = 0;
}

我尝试获取输出数据的方法

    private List<OutputItem> GetOutput(DateTime start, DateTime end, List<OutputItem> specificRanges)
    {
        List<OutputItem> periods = new List<OutputItem>();

        foreach (OutputItem sr in specificRanges)
        {
            if (start >= sr.Start && sr.End <= end)
            {
                periods.Add(new OutputItem { Start = sr.Start, End = sr.End, Coeff = sr.Coeff });
            }
        }

        return periods;
    }

【问题讨论】:

  • 我了解您的第一个示例,您只期望一个输出数据范围。但第二个例子不清楚。输入日期范围是否应该是 01.01.2016 - 29.04.2017(2017 年而不是 2016 年)?
  • 你有一个错误 From : start >= sr.Start To : start
  • 马吕斯,你是对的!第二个示例输入日期范围是 01.01.2016 - 29.04.2017

标签: c# datetime date-range


【解决方案1】:

所以我要在这里冒险并假设在您的第二个示例中,开始日期应该早于01-01-2016 - 因为如果我理解这个问题,您希望返回所有重叠的范围您传递给方法的开始到结束时间。
如果情况确实如此,那么您很接近 - 但您的情况是错误的。
测试两个范围是否重叠的方法是检查一个是否在另一个结束之前开始,反之亦然,正如您在 标签的 wiki 中看到的那样:

当两个或多个元素部分或完全相互覆盖时,它们会重叠。 判断元素是否重叠的方法是测试一个元素是否在第二个结束之前开始,而第二个在第一个结束之前开始。

所以你的方法应该是:

private List<OutputItem> GetOutput(DateTime start, DateTime end, List<OutputItem> specificRanges)
{
    List<OutputItem> periods = new List<OutputItem>();

    foreach (OutputItem sr in specificRanges)
    {
        if (start >= sr.End && sr.Start <= end)
        {
            periods.Add(new OutputItem { Start = sr.Start, End = sr.End, Coeff = sr.Coeff });
        }
    }

    return periods;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-28
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    相关资源
    最近更新 更多