0

Here is piece of code which creates random data with different datetime.

void ExtractEveryXminute()
{
     List<DataHolder> data = new List<DataHolder>();
     List<DateTime> randomTimes = new List<DateTime>();
     Random r = new Random();
     DateTime d = new DateTime(2019, 9, 19, 7, 0, 0);

     for (int i = 0; i < 100; i++)
     {
         DataHolder dh = new DataHolder();
         TimeSpan t = TimeSpan.FromSeconds(r.Next(0, 14400));  
         dh.OID = i;
         dh.Value = r.Next(50);
         dh.Snapshottime = d.Add(t);

         data.Add(dh);
      }

      data.OrderBy(o => o.Snapshottime).ToList();

      List<DataHolder> SortedList = data.OrderBy(o => o.Snapshottime).ToList();           

      var query_res = (from s in SortedList group s by new DateTime(s.Snapshottime.Year, s.Snapshottime.Month, s.Snapshottime.Day, s.Snapshottime.Hour, 15, 0));
}

public class DataHolder
{
    public int OID { get; set; }
    public double Value { get; set; }
    public DateTime Snapshottime { get; set; }       
}

I need to get data apart let's say every 15 minutes. Now I'm getting only datetime at 07:15:00, 8:15:00, 9:15:00 but this is not correct. How to extract those date starting from first record in list and filter every 15 minutes?

Josef
  • 2,648
  • 5
  • 37
  • 73
  • [Calling a method every x minutes](https://stackoverflow.com/questions/13019433/calling-a-method-every-x-minutes) – xdtTransform Sep 19 '19 at 09:01
  • @xdtTransform not applicable – Prophet Lamb Sep 19 '19 at 09:03
  • You are not going to ever get precisely down to the 100ns the time exactly at evvery 15 minutes. So sorted by time and then grouped by : new DateTime(Snapshottime.year, Snapshottime.month, Snapshottime.day, Snapshottime.hour, Snapshottime.minute/15, 0) then took first sample from each group. – jdweng Sep 19 '19 at 09:04
  • @xdtTransform i need to extract from list of objects not execute every 15 minutes – Josef Sep 19 '19 at 09:04
  • 1
    I dont think that you can do such a logic using LINQ, and if it is going to be very long and hard to read, thus bad for any project. You want to "select all items to which applies that the previous item that this statement applied to is a minimum of 900s^=15min" jounger <= thats your logic, for this you would have to remember the last element on which the statement applied and there just is not way to do this in LINQ decently. Because you would haveto use your result in the LINQ Statement which **IS DISASTROUS**. I would just opt in for C# Code with, some LINQ optimization. – Prophet Lamb Sep 19 '19 at 09:07
  • Like chunk a list of datetime with a timespan has chunk size? But from 8:00-8:15 or 1rst date +15mintues? – xdtTransform Sep 19 '19 at 09:19
  • Related: [LINQ aggregate and group by periods of time](https://stackoverflow.com/questions/8856266/linq-aggregate-and-group-by-periods-of-time) – xdtTransform Sep 19 '19 at 09:47

1 Answers1

2

You could use the following.

TimeSpan interval = new TimeSpan(0, 15, 0); 
var result = SortedList.GroupBy(x=> x.Snapshottime.Ticks/interval.Ticks)
                       .OrderBy(x=>x.Key);

Sample Output

enter image description here

Update

If, as per the comment, you want only the first time from each group of 15 min interval, then you could use.

var result = SortedList.GroupBy(x=> x.Snapshottime.Ticks/interval.Ticks)
                       .Select(x=>x.First());
Anu Viswan
  • 17,797
  • 2
  • 22
  • 51
  • I guess I should take each first value from each group or?!? – Josef Sep 19 '19 at 09:36
  • @Josef If you want only the first item from each 15 min groups, yes you can take the first one. But from the OP, i thought you need to group every data in groups of 15 min interval. – Anu Viswan Sep 19 '19 at 09:39
  • @Josef have updated the answer based on your comment. Kindly verify – Anu Viswan Sep 19 '19 at 09:41
  • both approaches are perfect. Is it possible to query with linq each group and take first value for this IOrderedEnumerable? – Josef Sep 19 '19 at 10:04