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