将日期范围分为几个特定的​​日期范围块

时间:2018-10-27 09:46:32

标签: c# datetime date-range

我有日期范围的常规列表,并带有特定值:

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 ,则需要获得一个输出日期范围和系数:< / p>

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

1 个答案:

答案 0 :(得分: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;
}