Linq group by DateTime / intervals
I've the following query
var x = from t in v
group t by t.Time.Year + "-" t.开发者_如何学运维Time.Month + "-" +
t.Time.Day + " " t.Time.Hour + ":" + t.Time.Minute into g
select new { Tag = g.Key, Frequency = g.Count() };
t.Time is a DateTime. The above smells a bit i.m.o. Are there any clean way to group by intervals based on DateTimes ?
Edit: What I don't quite like about this is the string fiddling and producing a string. Ideally I'd like to produce a DateTime out of the group, not a string.
Seems what I really wanted was
group t by
new DateTime(t.Time.Year,t.Time.Month,t.Time.Day ,t.Time.Hour,t.Time.Minute,0)
into g
None of the suggestiions involving Add/Subtract works for me, even if I also set the miliseconds to +.
dateTime.ToString("yyyy-MM-dd HH:mm") is a nice alternative to the strinc concatenation if I need a string though.
something like
group t by t.AddSeconds(60- t.Time.Seconds) // rounds to nearest minute
What about this:
DateTime[] v = new DateTime[]
{
new DateTime(2010, 01, 01, 01, 01, 00, 100),
new DateTime(2010, 01, 01, 01, 01, 30, 200),
new DateTime(2010, 01, 01, 02, 01, 00, 300),
new DateTime(2010, 01, 01, 03, 01, 45, 400)
};
var x = from t in v
//group t by t.ToString("yyyy-MM-dd HH:mm") into g
group t by t.AddSeconds(-t.TimeOfDay.TotalSeconds % 60) into g
select new { Tag = g.Key, Frequency = g.Count() };
EDIT: changed to .AddSeconds
, per @Colin suggestion
There are 600,000,000 ticks in a minute, so you could do something like this in order to group by the nearest minute:
var x = from t in v
group t by new DateTime(t.Time.Ticks - (t.Time.Ticks % 600000000)) into g
select new { Tag = g.Key, Frequency = g.Count() };
var x = from t in v
group t by t.Time.Date.AddMinutes((Int32)t.Time.TimeOfDay.TotalMinutes) into g
select new { Tag = g.Key, Frequency = g.Count() };
精彩评论