using System.Collections.Generic;
using System.Globalization;
public static void Main()
var entries = new EventRecord[]{
new EventRecord{DateAdded = DateTime.Parse("2006-12-30 00:38:54"), Event="click", Category = "externalWebsite"},
new EventRecord{DateAdded = DateTime.Parse("2006-07-20 00:36:44"), Event="click", Category = "social"},
new EventRecord{DateAdded = DateTime.Parse("2006-09-20 00:36:44"), Event="click", Category = "social"},
new EventRecord{DateAdded = DateTime.Parse("2006-09-22 00:12:34"), Event="load", Category = "profile"},
var dateRangeStart = DateTime.Parse("2006-01-01");
var dateRangeEnd = DateTime.Parse("2007-01-01");
var monthRange = MonthsBetween(dateRangeStart,dateRangeEnd);
var results = entries.Where(e => e.DateAdded>=dateRangeStart && e.DateAdded<dateRangeEnd)
Series = g.GroupBy(x => new {x.DateAdded.Month, x.DateAdded.Year})
foreach(var item in results)
Console.WriteLine($"Event:{item.Event} Category:{item.Category}");
var joinedSeries = from month in monthRange
join serie in item.Series
on new{month.Year, month.Month} equals new {serie.Year, serie.Month} into joined
from data in joined.DefaultIfEmpty()
Month = data == null ? month.Month : data.Month,
Year = data == null ? month.Year : data.Year,
Count = data == null ? 0 : data.Count
foreach(var serie in joinedSeries)
Console.WriteLine($"\t{CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(serie.Month)}{serie.Year} Count={serie.Count}");
private static IEnumerable<(int Month, int Year)> MonthsBetween(
iterator = new DateTime(startDate.Year, startDate.Month, 1);
iterator = new DateTime(endDate.Year, endDate.Month, 1);
var dateTimeFormat = CultureInfo.CurrentCulture.DateTimeFormat;
yield return (iterator.Month,iterator.Year);
iterator = iterator.AddMonths(1);
public class EventRecord {
public DateTime DateAdded {get;set;}
public string Event {get;set;}
public string Category {get;set;}