How to check if a DateTime range is within another 3 month DateTime range

喜你入骨 提交于 2019-12-01 04:19:39

You would call IntervalInQuarters as follows:

IntervalInQuarters(new DateTime(2007, 10, 10), new DateTime(2009, 10, 11));

The function returns a list of quarter start dates. Note that the range of quarters searched is defined within the function itself. Please edit as appropriate for your situation. They key point is to make sure the interval/quarter intersection logic is right.

private List<DateTime> IntervalInQuarters(DateTime myStartDate, DateTime myEndDate)
{
    DateTime quarterStart = new DateTime(2006, 06, 01);
    DateTime nextQuarterStart = new DateTime(2006, 09, 01);
    DateTime finalDate = new DateTime(2011, 01, 01);
    List<DateTime> foundQuarters = new List<DateTime>();

    while (quarterStart < finalDate)
    {
        // quarter intersects interval if:
        // its start/end date is within our interval
        // our start/end date is within quarter interval
        DateTime quarterEnd = nextQuarterStart.AddDays(-1);
        if (DateInInterval(myStartDate, quarterStart, quarterEnd) ||
            DateInInterval(myEndDate, quarterStart, quarterEnd) ||
            DateInInterval(quarterStart, myStartDate, myEndDate) ||
            DateInInterval(quarterEnd, myStartDate, myEndDate))
        {
            foundQuarters.Add(quarterStart);
        }

        quarterStart = nextQuarterStart;
        nextQuarterStart = nextQuarterStart.AddMonths(3);
    }

    return foundQuarters;
}

private bool DateInInterval(DateTime myDate, DateTime intStart, DateTime intEnd)
{
    return ((intStart <= myDate) && (myDate <= intEnd));
}

This should work for you also.

class Range
{
    public DateTime Begin { get; private set; }
    public DateTime End { get; private set; }
    public Range(DateTime begin, DateTime end)
    {
        Begin = begin;
        End = end;
    }

    public bool Contains(Range range)
    {
        return range.Begin >= Begin && range.End <= End;
    }
}

and then to use it

        List<Range> ranges = new List<Range>();

        ranges.Add(new Range(DateTime.Now, DateTime.Now.AddMonths(3)));
        ranges.Add(new Range(DateTime.Now.AddMonths(3), DateTime.Now.AddMonths(6)));

        Range test = new Range(DateTime.Now.AddMonths(1), DateTime.Now.AddMonths(2));

        var hits = ranges.Where(range => range.Contains(test));

        MessageBox.Show(hits.Count().ToString());
    private void Form1_Load(object sender, EventArgs e)
    {
        DateTime[,] ranges = new DateTime[3,2];
        //Range 1 - Jan to March
        ranges[0, 0] = new DateTime(2010, 1, 1);
        ranges[0, 1] = new DateTime(2010, 3, 1);
        //Range 2 - April to July
        ranges[1, 0] = new DateTime(2010, 4, 1);
        ranges[1, 1] = new DateTime(2010, 7, 1);
        //Range 3 - March to June
        ranges[2, 0] = new DateTime(2010, 3, 1);
        ranges[2, 1] = new DateTime(2010, 6, 1);

        DateTime checkDate = new DateTime(2010, 4, 1);
        string validRanges = string.Empty;

        for (int i = 0; i < ranges.GetLength(0); i++)
        {
            if (DateWithin(ranges[i,0], ranges[i,1], checkDate))
            {
                validRanges += i.ToString() + " ";
            }
        }
        MessageBox.Show(validRanges);
    }

    private bool DateWithin(DateTime dateStart, DateTime dateEnd, DateTime checkDate)
    {
        if (checkDate.CompareTo(dateStart) < 0 || checkDate.CompareTo(dateEnd) > 0)
        {
            return false;
        }
        return true;
    }

You may have to take a look at: http://msdn.microsoft.com/en-us/library/03ybds8y(v=VS.100).aspx

This may start you up

FindQuarter(DateTime startDate, DateTime endDate) // 01-10-09, 01-06-10
{
    startDateQuarter = GetQuarter(startDate.Month); // 2
    endDateQuarter = GetQuarter(endDate.Month);  // 1
    endDateQuarter += (endDate.Year - startDate.Year) * 4; // 5
    // fill up startDateQuarter to endDateQuarter into a list 
    // and return it // 2,3,4,5
}


GetQuarter(int month) // 6
{
    int quarter;
    // check the month value and accordingly assign one of the basic quarters 
    // using if-else construct ie, if(month>=6 && month<=8){ quarter = 1 };
    return quarter; // 1 
}

Instead of GetQuarter() method, you can also use a dictionary to store your month to quarter mappings

Dictionary<int, int> quarter = new Dictionary<int, int>();
quarter.Add(1,1);  //of the format Add(month,quarter)
quarter.Add(2,1);
...

Now instead of GetQuarter(someDate.Month); you can use quarter[someDate.Month];

If you want to compare two dates you should find out the first day of the quarter corresponds every of this dates, then you can compare this two dates:

using System;

namespace DataTime {
    class Program {
        static int GetQuarter (DateTime dt) {
            int Month = dt.Month;   // from 1 to 12
            return Month / 3 + 1;
        }
        static DateTime GetQuarterFirstDay (DateTime dt) {
            int monthsOfTheFirstDayOfQuarter = (GetQuarter (dt) - 1) * 3 + 1;
            return new DateTime(dt.Year, monthsOfTheFirstDayOfQuarter, 1);
            // it can be changed to
            //  return new DateTime(dt.Year, (dt.Month/3)*3 + 1, 1);
        }
        static void Main (string[] args) {
            DateTime dt1 = new DateTime (2009, 6, 9),
                     dt2 = new DateTime (2009, 7, 9),
                     dt3 = new DateTime (2009, 8, 9),
                     dt4 = new DateTime (2009, 8, 9);

            Console.WriteLine ("dt1={0}", dt1.AddMonths (1));
            Console.WriteLine ("dt2={0}", dt2.AddMonths (1));
            Console.WriteLine ("dt3={0}", dt3.AddMonths (1));

            DateTime startDate = DateTime.Now,
                     endDate1 = startDate.AddMonths(24).AddDays(1),
                     endDate2 = startDate.AddMonths(24).AddDays(-1),
                     endDate3 = startDate.AddMonths(28);
            Console.WriteLine ("Now we have={0}", startDate);
            Console.WriteLine ("endDate1={0}", endDate1);
            Console.WriteLine ("endDate2={0}", endDate2);
            Console.WriteLine ("endDate3={0}", endDate3);

            Console.WriteLine ("GetQuarterFirstDay(startDate)={0}", GetQuarterFirstDay (startDate));
            Console.WriteLine ("GetQuarterFirstDay(endDate1)={0}", GetQuarterFirstDay (endDate1));
            Console.WriteLine ("GetQuarterFirstDay(endDate2)={0}", GetQuarterFirstDay (endDate2));
            Console.WriteLine ("GetQuarterFirstDay(endDate3)={0}", GetQuarterFirstDay (endDate3));
            if (DateTime.Compare (GetQuarterFirstDay (endDate2), GetQuarterFirstDay (startDate).AddMonths (24)) > 0)
                Console.WriteLine ("> 2 Yeas");
            else
                Console.WriteLine ("<= 2 Yeas");
            if (DateTime.Compare (GetQuarterFirstDay (endDate3), GetQuarterFirstDay (startDate).AddMonths (24)) > 0)
                Console.WriteLine ("> 2 Yeas");
            else
                Console.WriteLine ("<= 2 Yeas");
        }
    }
}

produce

dt1=09.07.2009 00:00:00
dt2=09.08.2009 00:00:00
dt3=09.09.2009 00:00:00
Now we have=22.04.2010 11:21:45
endDate1=23.04.2012 11:21:45
endDate2=21.04.2012 11:21:45
endDate3=22.08.2012 11:21:45
GetQuarterFirstDay(startDate)=01.04.2010 00:00:00
GetQuarterFirstDay(endDate1)=01.04.2012 00:00:00
GetQuarterFirstDay(endDate2)=01.04.2012 00:00:00
GetQuarterFirstDay(endDate3)=01.07.2012 00:00:00
<= 2 Yeas
> 2 Yeas

EDITED: I fixed an error from the first version. Now it should works correct.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!