score:1

I will propose 2 solutions for your problem, depend on the length of your list one will be better.

Initialize :

``````var myList = new List<DataRecord>
{
new DataRecord
{
MeasurementDate = new DateTime(2019, 1, 31, 11, 50, 0)
},
new DataRecord
{
MeasurementDate = new DateTime(2019, 1, 31, 17, 21, 0)
},
new DataRecord
{
MeasurementDate = new DateTime(2019, 1, 31, 17, 59, 0)
},
new DataRecord
{
MeasurementDate = new DateTime(2019, 1, 31, 10, 54, 0)
},
new DataRecord
{
MeasurementDate = new DateTime(2019, 1, 31, 11, 54, 0)
},
};

List<DataRecord> result = new List<DataRecord>();
``````

Solution 1 :

``````var minimumMinutes = myList.Min(x => x.MeasurementDate.Hour * 60 + x.MeasurementDate.Minute);
var maximumMinutes = myList.Max(x => x.MeasurementDate.Hour * 60 + x.MeasurementDate.Minute);

for (int minutes = minimumMinutes; minutes < maximumMinutes; minutes++)
{
var list = myList.Where(x =>
x.MeasurementDate.Hour * 60 + x.MeasurementDate.Minute <= minutes + 60 &&
x.MeasurementDate.Hour * 60 + x.MeasurementDate.Minute >= minutes);

if (result.Count < list.Count())
{
result = list.ToList();
}
}
``````

Solution 2 :

``````foreach (var dataRecord in myList)
{
var minutes = dataRecord.MeasurementDate.Hour * 60 + dataRecord.MeasurementDate.Minute;
var before = myList.Where(x =>
x.MeasurementDate.Hour * 60 + x.MeasurementDate.Minute >= minutes - 60 &&
x.MeasurementDate.Hour * 60 + x.MeasurementDate.Minute <= minutes).ToList();
var after = myList.Where(x =>
x.MeasurementDate.Hour * 60 + x.MeasurementDate.Minute <= minutes + 60 &&
x.MeasurementDate.Hour * 60 + x.MeasurementDate.Minute >= minutes).ToList();

if (before.Count > result.Count ||
after.Count > result.Count)
{
result = before.Count > after.Count ? before.ToList() : after.ToList();
}
}
``````

score:1

As I mentioned in comments this code is not performance efficient, but this will do the trick.

``````// DummyData
List<DateTime> dates = new List<DateTime>
{
DateTime.Parse("2019/01/31 11:50"),
DateTime.Parse("2019/02/02 17:21"),
DateTime.Parse("2019/03/01 17:59"),
DateTime.Parse("2019/03/12 10:54"),
DateTime.Parse("2019/05/28 11:15"),
};

// Storage for final Output
List<DateTime> finalOp = new List<DateTime>();

// Main logic goes here
// foreach Hour in list we will compare that with every other Hour in list
// and it is in 1 hour range we will add it to list
foreach (DateTime dateTime in dates)
{
List<DateTime> temp = new List<DateTime>();
foreach (DateTime innerDateTime in dates)
{
// find the difference between two hours
var timeSpan = dateTime.TimeOfDay - innerDateTime.TimeOfDay;

// add it to same list if we have +/- 1 Hour difference
if (timeSpan.TotalHours <= 1 && timeSpan.TotalHours >= -1)
{
}

}

// once we have final group for date we will check if this has maximum number of common dates around
// if so replace it with previous choice
if (finalOp.Count < temp.Count)
{
finalOp = temp;
}
}

// print the results
foreach (var data in finalOp)
{
Console.WriteLine(data.ToShortTimeString());
}
``````

score:0

For the 10,000 items of `myList` collection this solution can be fast:

``````private static List<DataRecord> Get(List<DataRecord> myList)
{
var ordered = myList.OrderBy(x => x.MeasurementDate.TimeOfDay).ToList();
int i = 0;
int count = myList.Count();
var temp =
(from s in ordered
let index = ++i
let next = ordered.ElementAtOrDefault(index != count ? index : 0)
select new
{
Cur = s.MeasurementDate,
Diff = index != count
? (next.MeasurementDate.TimeOfDay - s.MeasurementDate.TimeOfDay).TotalMinutes
: 24 * 60 - (ordered.ElementAtOrDefault(count - 1).MeasurementDate.TimeOfDay - ordered.ElementAtOrDefault(0).MeasurementDate.TimeOfDay).TotalMinutes
}).ToList();

Dictionary<int, int> dict = new Dictionary<int, int>();
count = 0;
double minutes = 0;
for (int index = 0; index < temp.Count(); index++)
{
for (int j = index; j < temp.Count(); j++)
{
minutes += temp[j].Diff;
if (minutes > 60)
{
count = 0;
minutes = 0;
break;
}
else
{
count++;
}
}
}

var max = dict.First(d => d.Value == dict.Values.Max());
var finalResult = ordered.Skip(max.Key).Take(max.Value + 1).ToList();
return finalResult;
}
``````

Please note it returns ordered results.