Is there a simple function for rounding a DateTime down to the nearest 30 minutes, in C#?

Solution 1:

DateTime RoundDown(DateTime dt, TimeSpan d)
{
    return new DateTime((dt.Ticks / d.Ticks) * d.Ticks);
}

Example:

var dt1 = RoundDown(DateTime.Parse("2011-08-11 16:59"), TimeSpan.FromMinutes(30));
// dt1 == {11/08/2011 16:30:00}

var dt2 = RoundDown(DateTime.Parse("2011-08-11 17:00"), TimeSpan.FromMinutes(30));
// dt2 == {11/08/2011 17:00:00}

var dt3 = RoundDown(DateTime.Parse("2011-08-11 17:01"), TimeSpan.FromMinutes(30));
// dt3 == {11/08/2011 17:00:00}

Solution 2:

I would say something like that

var time = DateTime.Now;
var rounded = time.AddMinutes(
        time.Minute>30 ? -(time.Minute-30) : -time.Minute) 

And you could even do your own extension

public static class TimeHelper {
   public static DateTime RoundDown (this DateTime time)
   {
       return time.AddMinutes(
         time.Minute>30 ? -(time.Minute-30) : -time.Minute);
   }
}

EDIT

This function cut's also the seconds / milliseconds if necessary. Thanks for the hint.

public static DateTime RoundDown(this DateTime time)
{
    return time.Subtract(
        new TimeSpan(0, 0, time.Minute > 30 ? (time.Minute - 30) : time.Minute, 
            time.Second, time.Millisecond));
}

Solution 3:

A more generic solution rounding to the nearest time span:


public static DateTime RoundUp(this DateTime dt, TimeSpan d)
{
    var delta = (d.Ticks - (dt.Ticks % d.Ticks)) % d.Ticks;
    return new DateTime(dt.Ticks + delta);
}

public static DateTime RoundDown(this DateTime dt, TimeSpan d)
{
    var delta = dt.Ticks % d.Ticks;
    return new DateTime(dt.Ticks - delta);
}

public static DateTime RoundToNearest(this DateTime dt, TimeSpan d)
{
    var delta = dt.Ticks % d.Ticks;
    bool roundUp = delta > d.Ticks / 2;

    return roundUp ? dt.RoundUp(d) : dt.RoundDown(d);
}

It would be used this way:

var date = new DateTime(2010, 02, 05, 10, 35, 25, 450); // 2010/02/05 10:35:25
var rounded = date.RoundToNearest(TimeSpan.FromMinutes(30)); // 2010/02/05 10:30:00

More in this response.

Solution 4:

DateTime newDateTime = new DateTime(oldDateTime.Year, oldDateTime.Month, oldDateTime.Day
  ,oldDateTime.Hour, (oldDateTime.Minute / 30) * 30, 0);