给定一个从StartingDateEndingDate的时间段。
我想获得从给定StartingMonthEndingMonth开始的那段时间间隔。

范例:

StartingMonth = april (4)
EndingMonth = november (11)


期间:

Period A : StartingDate =  (2014, 03, 01); EndingDate = (2015, 02, 28);
Period B : StartingDate =  (2014, 07, 01); EndingDate = (2015, 06, 30);
Period C : StartingDate =  (2014, 01, 01); EndingDate = (2015, 12, 31);


将返回:

Period A : 1 sub-period = (2014, 4, 1) - (2014, 11, 30)
Period B : 2 sub-periods = (2014, 7, 1) - (2014, 11, 30) ; (2015, 4, 1) - (2015, 6, 30)
Period C : 2 sub-periods = (2014, 4, 1) - (2014, 11, 30) ; (2015, 4, 1) - (2015, 11, 30)


我已经尝试过此方法(似乎是很难的方法,并且无法管理多个子周期):
使用LINQ可能更简单吗?

if (StartingDate.Month < startingMonth && EndingDate.Month < endingMonth)
{
    periods.Add(new PeriodInterval
    {
        StartDate = new DateTime(StartingDate.Year, startingMonth, 1),
        EndDate = new DateTime(StartingDate.Year, endingMonth, EndingDate.Day)
    });
}

if (StartingDate.Month > startingMonth && EndingDate.Month > endingMonth)
{
     periods.Add(new PeriodInterval
    {
       StartDate = new DateTime(StartingDate.Year, startingMonth, 1),
       EndDate = new DateTime(StartingDate.Year, endingMonth, EndingDate.Day)
     });
}

if (StartingDate.Month < startingMonth && EndingDate.Month > endingMonth)
{
    periods.Add(new PeriodInterval
    {
        StartDate = new DateTime(StartingDate.Year, startingMonth, 1),
        EndDate = new DateTime(StartingDate.Year, endingMonth, EndingDate.Day)
    });
}

if (StartingDate.Month > startingMonth && EndingDate.Month < endingMonth)
{
    periods.Add(new PeriodInterval
    {
        StartDate = new DateTime(StartingDate.Year, startingMonth, 1),
        EndDate = new DateTime(StartingDate.Year, endingMonth, EndingDate.Day)
    });
}


这个想法是在红色时段内返回蓝色时段:

最佳答案

class Discount
{
    public int DiscountID { get; set; } //You will need some Key field if you are storing these in a database.
    public DateTime issueDate { get; set; }
    public DateTime expirationDate { get; set; }

    public List<PeriodInterval> intervals { get; set; }

    public Discount(DateTime IssueDate, DateTime ExpirationDate)
    {
        issueDate = IssueDate;
        expirationDate = ExpirationDate;
        intervals = new List<PeriodInterval>();
    }

    public void AddInterval(DateTime StartDate, DateTime EndDate)
    {
        intervals.Add(new PeriodInterval() {
            StartMonth=StartDate.Month,
            StartDay=StartDate.Day,
            EndMonth=EndDate.Month,
            EndDay=EndDate.Day
        });
    }
    public List<Period> GetPeriods()
    {
        List<Period> periods=new List<Period>();
        int yearCount = expirationDate.Year-issueDate.Year+1; //+1: Run at least one year against the periods.
        for (int i = 0; i < yearCount; i++)
        {
            //Loop through all the years and add 'Periods' from all the PeriodInterval info.
            foreach (PeriodInterval pi in intervals)
            {
                var period = pi.GetPeriod(issueDate, expirationDate, i);
                if (period != null)
                    periods.Add(period);
            }
        }
        return periods;
    }
}
class Period
{
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}
class PeriodInterval
{
    public int PeriodIntervalID { get; set; } //You will need some Key field if you are storing these in a database.
    public int DiscountID { get; set; } //Foreign Key to Discount. This is alsof for database storage.

    public int StartMonth { get; set; }
    public int StartDay { get; set; }

    public int EndMonth { get; set; }
    public int EndDay { get; set; }

    public Period GetPeriod(DateTime issueDate, DateTime expirationDate, int Year)
    {
        DateTime PeriodStart = new DateTime(issueDate.AddYears(Year).Year, StartMonth, StartDay);
        DateTime PeriodEnd = new DateTime(issueDate.AddYears(Year).Year, EndMonth, EndDay);

        PeriodStart=new DateTime(Math.Max(PeriodStart.Ticks, issueDate.Ticks)); //Limit period to the max of the two start dates.
        PeriodEnd = new DateTime(Math.Min(PeriodEnd.Ticks, expirationDate.Ticks)); //Limit period to the min of the two end dates.

        if(PeriodEnd>PeriodStart) //If a valid period
        {
            return new Period()
            {
                StartDate = PeriodStart,
                EndDate = PeriodEnd
            };
        }
        //Default Return Null
        return null;
    }
}


我构建了一个控制台应用程序来进行测试:

static void Main(string[] args)
{
    List<Discount> Discounts = new List<Discount>();

    Discount d1 = new Discount(new DateTime(2014, 3, 1), new DateTime(2015, 02, 28));
    Discount d2 = new Discount(new DateTime(2014, 7, 1), new DateTime(2015, 06, 30));
    Discount d3 = new Discount(new DateTime(2014, 01, 1), new DateTime(2015, 12, 31));

    Discounts.Add(d1);
    Discounts.Add(d2);
    Discounts.Add(d3);

    foreach (Discount d in Discounts)
    {
        d.AddInterval(new DateTime(2014, 4, 1), new DateTime(2014, 11, 30));

        Console.WriteLine("IssueDate:{0} ExpirationDate:{1}", d.issueDate, d.expirationDate);
        foreach (Period p in d.GetPeriods())
        {
            Console.WriteLine("Start:{0} End:{1}", p.StartDate, p.EndDate);
        }
    }

    Console.ReadLine();
}


这是打印出来的内容:

关于c# - 提取期间内的子期间,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24656848/

10-11 04:49