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