Assuming you're able to use LINQ, then you can do all the grouping and ordering in the C# fairly easily. (I'm assuming just a list of DateTime objects rather than full Show objects -- it would appear you can get the DateTime for each Show with a simple LINQ Select statement.)
var shows = new[]
{
new DateTime(2010, 7, 28, 11, 15, 0),
new DateTime(2010, 7, 29, 8, 50, 0),
new DateTime(2010, 7, 29, 8, 55, 0)
};
var dates = shows.GroupBy(d => d.Date).OrderBy(d => d.Key);
foreach (var date in dates)
{
Console.WriteLine("Date {0}", date.Key.ToShortDateString());
var hours = date.GroupBy(d => d.Hour).OrderBy(d => d.Key);
Console.WriteLine("\tHours\tCount");
foreach (var hour in hours)
Console.WriteLine("\t{0}-{1}\t{2}", hour.Key, (hour.Key+1)%24, hour.Count());
}
This provides the output:
Date 7/28/2010
Hours Count
11-12 1
Date 7/29/2010
Hours Count
8-9 2
Note that this is just a simple Console Application example. You have not specified what GUI technology you are using (WinForms, WPF), so I'll leave it as an exercise to take the grouping results and apply them in a GUI.
Edit: Here is an example format in XAML using nested ItemsControls with DataBinding to a LINQ statement.
<ItemsControl Name="ShowDates" ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<HeaderedContentControl HeaderStringFormat="Date: {0}">
<HeaderedContentControl.Header>
<StackPanel>
<TextBlock Text="{Binding Path=DateString, StringFormat='Date: {0}'}" />
<TextBlock Margin="20,1,1,1" Text="Hour : Shows"/>
</StackPanel>
</HeaderedContentControl.Header>
<ItemsControl Name="HoursList" Margin="20,1,1,1" ItemsSource="{Binding Path=Hours}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}-{1} : {2}">
<MultiBinding.Bindings>
<Binding Path="HourStart" />
<Binding Path="HourEnd" />
<Binding Path="Count" />
</MultiBinding.Bindings>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</HeaderedContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This uses a modified version of my original LINQ statement to make it easier for the DataBinding to be wired up. This code is in the constructor of my test Window.
var result =
shows
.GroupBy(d => d.Date)
.Select(gp => new{
Date = gp.Key,
DateString = gp.Key.ToShortDateString(),
Hours = gp.GroupBy(d => d.Hour)
.Select(hgp => new {
HourStart = hgp.Key,
HourEnd = (hgp.Key + 1) % 24,
Count = hgp.Count()
})
.OrderBy(h => h.HourStart)
});
ShowDates.DataContext = result;