Given years, speed, and extensibility, this can be done as an enumerated extension (possibly even using a universal property selector). If dates have already been truncated to a month and the list is ordered before FillMissing is executed, consider this method:
public static class Extensions { public static IEnumerable<Tuple<DateTime, int>> FillMissing(this IEnumerable<Tuple<DateTime, int>> list) { if(list.Count() == 0) yield break; DateTime lastDate = list.First().Item1; foreach(var tuple in list) { lastDate = lastDate.AddMonths(1); while(lastDate < tuple.Item1) { yield return new Tuple<DateTime, int>(lastDate, 0); lastDate = lastDate.AddMonths(1); } yield return tuple; lastDate = tuple.Item1; } } }
and in the form of an example:
private List<Tuple<DateTime, int>> items = new List<Tuple<DateTime, int>>() { new Tuple<DateTime, int>(new DateTime(2010, 1, 1), 3), new Tuple<DateTime, int>(new DateTime(2010, 2, 1), 4), new Tuple<DateTime, int>(new DateTime(2010, 4, 1), 2), new Tuple<DateTime, int>(new DateTime(2010, 5, 1), 2), new Tuple<DateTime, int>(new DateTime(2010, 8, 1), 3), new Tuple<DateTime, int>(new DateTime(2010, 9, 1), -3), new Tuple<DateTime, int>(new DateTime(2010, 10, 1), 6), new Tuple<DateTime, int>(new DateTime(2010, 11, 1), 3), new Tuple<DateTime, int>(new DateTime(2010, 12, 1), 7), new Tuple<DateTime, int>(new DateTime(2011, 2, 1), 3) }; public Form1() { InitializeComponent(); var list = items.FillMissing(); foreach(var element in list) { textBox1.Text += Environment.NewLine + element.Item1.ToString() + " - " + element.Item2.ToString(); } }
which will result in a text box containing:
2010-01-01 00:00:00 - 3 2010-02-01 00:00:00 - 4 2010-03-01 00:00:00 - 0 2010-04-01 00:00:00 - 2 2010-05-01 00:00:00 - 2 2010-06-01 00:00:00 - 0 2010-07-01 00:00:00 - 0 2010-08-01 00:00:00 - 3 2010-09-01 00:00:00 - -3 2010-10-01 00:00:00 - 6 2010-11-01 00:00:00 - 3 2010-12-01 00:00:00 - 7 2011-01-01 00:00:00 - 0 2011-02-01 00:00:00 - 3