This code will let you "round" a date time to any given interval. You can get the floor or ceiling, or do a traditional round.
Here's the code:
public static class Extensions { public static DateTime Floor(this DateTime date, TimeSpan span) { if (span == TimeSpan.FromMinutes(0)) return date; long ticks = date.Ticks / span.Ticks; return new DateTime(ticks * span.Ticks); } public static DateTime Ceil(this DateTime date, TimeSpan span) { if (span == TimeSpan.FromMinutes(0)) return date; long ticks = (date.Ticks + span.Ticks - 1) / span.Ticks; return new DateTime(ticks * span.Ticks); } public static DateTime Round(this DateTime date, TimeSpan span) { if (span == TimeSpan.FromMinutes(0)) return date; long ticks = (date.Ticks + (span.Ticks / 2)) / span.Ticks; return new DateTime(ticks * span.Ticks); } }
Here's a simple example using Floor:
DateTime dt = new DateTime(2010, 8, 29, 15, 26, 23); Console.WriteLine("Floor:"); Console.WriteLine(dt.Floor(TimeSpan.FromSeconds(0))); Console.WriteLine(dt.Floor(TimeSpan.FromMinutes(1))); Console.WriteLine(dt.Floor(TimeSpan.FromMinutes(5))); Console.WriteLine(dt.Floor(TimeSpan.FromMinutes(10))); Console.WriteLine(dt.Floor(TimeSpan.FromMinutes(60))); Console.WriteLine(); Console.WriteLine("Ceil:"); Console.WriteLine(dt.Ceil(TimeSpan.FromSeconds(0))); Console.WriteLine(dt.Ceil(TimeSpan.FromMinutes(1))); Console.WriteLine(dt.Ceil(TimeSpan.FromMinutes(5))); Console.WriteLine(dt.Ceil(TimeSpan.FromMinutes(10))); Console.WriteLine(dt.Ceil(TimeSpan.FromMinutes(60))); Console.WriteLine(); Console.WriteLine("Round:"); Console.WriteLine(dt.Round(TimeSpan.FromSeconds(0))); Console.WriteLine(dt.Round(TimeSpan.FromMinutes(1))); Console.WriteLine(dt.Round(TimeSpan.FromMinutes(5))); Console.WriteLine(dt.Round(TimeSpan.FromMinutes(10))); Console.WriteLine(dt.Round(TimeSpan.FromMinutes(60))); Console.ReadKey();
And here's the output:
Floor: 8/29/2010 3:26:23 PM 8/29/2010 3:26:00 PM 8/29/2010 3:25:00 PM 8/29/2010 3:20:00 PM 8/29/2010 3:00:00 PM Ceil: 8/29/2010 3:26:23 PM 8/29/2010 3:27:00 PM 8/29/2010 3:30:00 PM 8/29/2010 3:30:00 PM 8/29/2010 4:00:00 PM Round: 8/29/2010 3:26:23 PM 8/29/2010 3:26:00 PM 8/29/2010 3:25:00 PM 8/29/2010 3:30:00 PM 8/29/2010 3:00:00 PM