1

I am having a hard time to come up with a clean solution with the following problem. I need to find an index of given date between time interval (date from/date to) based on monthly resolution.

Example:

date format = yyyy-MM-dd
timeIntervalFrom = 2016-02-01
timeIntervalTo = 2017-03-01
searchDate = 2017-01-01

Here the index would be 11.

The only thing I have come up with is brute force search, but I feel there is a cleaner way to solve this problem via some math.

var index = 0;
while (timeIntervalFrom < timeIntervalTo)
{
    if (timeIntervalFrom == searchDate)
        break;

    index++;
    timeIntervalFrom = timeIntervalFrom.AddMonths(1);
}

Any suggestion will be much appreciated!

Edit:

Here is a compilable solution which shows that using @Pikoh solution stops working correctly when time interval is wider due to months having different length, so that is not a viable solution.

using System;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            int endYear = 2022;

            var index1 = FindIndex1(new DateTime(2016, 1, 1), new DateTime(endYear, 3, 1), new DateTime(endYear, 2, 1));
            var index2 = FindIndex2(new DateTime(2016, 1, 1), new DateTime(endYear, 3, 1), new DateTime(endYear, 2, 1));

            Console.Out.WriteLine($"FindIndex1: {index1}, FindIndex2: {index2}, Result: {(index1 == index2 ? "OK" : "FAIL")}");
        }

        private static int FindIndex1(DateTime timeIntervalFrom, DateTime timeIntervalTo, DateTime searchDate)
        {
            var index = 0;
            while (timeIntervalFrom < timeIntervalTo)
            {
                if (timeIntervalFrom == searchDate)
                    break;

                index++;
                timeIntervalFrom = timeIntervalFrom.AddMonths(1);
            }

            return index;
        }

        private static int FindIndex2(DateTime timeIntervalFrom, DateTime timeIntervalTo, DateTime searchDate)
        {
            return (searchDate - timeIntervalFrom).Days / 30;
        }
    }
}

Edit2:

I've managed to find the right solution reading provided link @Charles Mager gave. So in a way @Pikoh was very close. Thank you both very much!

private static int FindIndex3(DateTime timeIntervalFrom, DateTime searchDate)
{
    return (int) (searchDate.Subtract(timeIntervalFrom).Days / (365.2425 / 12));
}
DavorinP
  • 237
  • 1
  • 5
  • 14
  • 2
    It sounds a lot like [Difference in months between two dates](http://stackoverflow.com/questions/4638993/difference-in-months-between-two-dates) with `searchDate.Subtract(timeIntervalFrom)`. – Charles Mager Oct 18 '16 at 08:15
  • Index means number of months since from Date? if so, try `var index = (searchDate - timeIntervalFrom).Days/30;` – Pikoh Oct 18 '16 at 08:17
  • I don't understand why you have three values. You don't use `searchDate` in your example – LordWilmore Oct 18 '16 at 08:29
  • Why do you say my solution does not work? if my calculations are ok, from january, 2016 to march,2022 there are 75 months...what should the correct result be in your opinion? – Pikoh Oct 18 '16 at 09:08

1 Answers1

0

Try below code:

 private static int FindIndex(DateTime timeIntervalFrom, DateTime timeIntervalTo, DateTime searchDate)
    {

        var index = -1;
        if (searchDate.CompareTo(timeIntervalFrom) >= 0 && searchDate.CompareTo(timeIntervalTo) <= 0)
        {
            index = (searchDate.Year - timeIntervalFrom.Year) * 12
                + (searchDate.Month > timeIntervalFrom.Month ? searchDate.Month - timeIntervalFrom.Month
                : searchDate.Month + 12 - timeIntervalFrom.Month);
        }

        return index;
    }
Dinesh Singh
  • 210
  • 1
  • 4